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:
285
src/Nazara/Audio/Audio.cpp
Normal file
285
src/Nazara/Audio/Audio.cpp
Normal 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;
|
||||
@@ -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
|
||||
15
src/Nazara/Audio/Loaders/sndfile.hpp
Normal file
15
src/Nazara/Audio/Loaders/sndfile.hpp
Normal 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
|
||||
135
src/Nazara/Audio/Loaders/sndfile/Loader.cpp
Normal file
135
src/Nazara/Audio/Loaders/sndfile/Loader.cpp
Normal 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
180
src/Nazara/Audio/Sound.cpp
Normal 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);
|
||||
}
|
||||
229
src/Nazara/Audio/SoundBuffer.cpp
Normal file
229
src/Nazara/Audio/SoundBuffer.cpp
Normal 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;
|
||||
156
src/Nazara/Audio/SoundEmitter.cpp
Normal file
156
src/Nazara/Audio/SoundEmitter.cpp
Normal 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;
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
46
src/Nazara/Core/ConditionVariable.cpp
Normal file
46
src/Nazara/Core/ConditionVariable.cpp
Normal 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
39
src/Nazara/Core/Core.cpp
Normal 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;
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
/*
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
/**
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 += " (";
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
138
src/Nazara/Core/Resource.cpp
Normal file
138
src/Nazara/Core/Resource.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
26
src/Nazara/Core/ResourceListener.cpp
Normal file
26
src/Nazara/Core/ResourceListener.cpp
Normal 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);
|
||||
}
|
||||
@@ -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>
|
||||
|
||||
18
src/Nazara/Core/Stream.cpp
Normal file
18
src/Nazara/Core/Stream.cpp
Normal 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;
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
24
src/Nazara/Core/Win32/Time.cpp
Normal file
24
src/Nazara/Core/Win32/Time.cpp
Normal 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);
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
}
|
||||
|
||||
728
src/Nazara/Renderer/RenderTexture.cpp
Normal file
728
src/Nazara/Renderer/RenderTexture.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
162
src/Nazara/Utility/AxisAlignedBox.cpp
Normal file
162
src/Nazara/Utility/AxisAlignedBox.cpp
Normal 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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user