First part of render texture commit

Added NzContext::EnsureContext and NzContext::GetThreadContext
Added NzCube
Added NzRect::GetCenter
Added methods to send vectors to shaders
Added NzRenderer::SetViewport
Fixed NzRect::ExtendTo calculations
Fixed NzImage::Update checks with level > 0
No longer use glTexStorage when creating a texture to prevent a bug
NzBuffer's Lock and Unlock operations renamed to Map and Unmap
NzVector2/3/4 can now cast implicitly to a pointer
Optimized compilation time of String.hpp
Optimized normalisaton of quaternions
Optimized passing uniforms to shaders
Quaternion now automaticaly Normalize h
Removed macro definition of NAZARA_RENDERER_OPENGL from Renderer
Removed implicit cast from NzVector2/3/4 to NzString
Renamed nzBufferLock to nzBufferAccess
Renamed NzRenderTarget::CanActivate to IsValid
This commit is contained in:
Lynix
2012-06-13 07:40:31 +02:00
parent b1632842ae
commit e2a38b3790
55 changed files with 1400 additions and 417 deletions

View File

@@ -313,7 +313,7 @@ std::size_t NzFile::Read(void* buffer, std::size_t typeSize, unsigned int count)
{
unsigned int typeCount = byteRead/typeSize;
for (unsigned int i = 0; i < typeCount; ++i)
NzByteSwap(static_cast<char*>(buffer) + i*typeSize, typeSize);
NzByteSwap(reinterpret_cast<nzUInt8*>(buffer) + i*typeSize, typeSize);
}
return byteRead;

View File

@@ -8,7 +8,7 @@
#include <Nazara/Core/Debug.hpp>
NzMemoryStream::NzMemoryStream(const void* ptr, nzUInt64 size) :
m_ptr(static_cast<const nzUInt8*>(ptr)),
m_ptr(reinterpret_cast<const nzUInt8*>(ptr)),
m_pos(0),
m_size(size)
{

View File

@@ -67,7 +67,7 @@ void NzThreadImpl::Terminate()
unsigned int _stdcall NzThreadImpl::ThreadProc(void* userdata)
{
NzThread* owner = static_cast<NzThread*>(userdata);
NzThread* owner = reinterpret_cast<NzThread*>(userdata);
NzFunctor* func = owner->m_func;
HANDLE myHandle = owner->m_impl->m_thread;
func->Run();

View File

@@ -50,17 +50,17 @@ NzBuffer::~NzBuffer()
bool NzBuffer::CopyContent(NzBuffer& buffer)
{
void* ptr = buffer.Lock(nzBufferLock_ReadOnly);
void* ptr = buffer.Map(nzBufferAccess_ReadOnly);
if (!ptr)
{
NazaraError("Unable to lock source buffer");
NazaraError("Failed to map source buffer");
return false;
}
bool r = Fill(ptr, 0, m_length);
if (!buffer.Unlock())
NazaraWarning("Unable to unlock source buffer");
if (!buffer.Unmap())
NazaraWarning("Failed to unmap source buffer");
return r;
}
@@ -205,7 +205,7 @@ bool NzBuffer::IsHardware() const
return m_storage == nzBufferStorage_Hardware;
}
void* NzBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length)
void* NzBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -221,10 +221,10 @@ void* NzBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length
}
#endif
return m_impl->Lock(lock, offset*m_typeSize, length*m_typeSize);
return m_impl->Map(access, offset*m_typeSize, length*m_typeSize);
}
bool NzBuffer::Unlock()
bool NzBuffer::Unmap()
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
@@ -234,7 +234,7 @@ bool NzBuffer::Unlock()
}
#endif
return m_impl->Unlock();
return m_impl->Unmap();
}
bool NzBuffer::IsSupported(nzBufferStorage storage)

View File

@@ -26,8 +26,8 @@ class NzBufferImpl
virtual bool IsHardware() const = 0;
virtual void* Lock(nzBufferLock lock, unsigned int offset = 0, unsigned int size = 0) = 0;
virtual bool Unlock() = 0;
virtual void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int size = 0) = 0;
virtual bool Unmap() = 0;
};
#endif // NAZARA_BUFFERIMPL_INCLUDED

View File

@@ -8,6 +8,7 @@
#include <Nazara/Core/Log.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <vector>
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
@@ -21,9 +22,10 @@
namespace
{
///TODO: Thread-local
NzContext* currentContext = nullptr;
NzContext* threadContext = nullptr;
NAZARA_THREADLOCAL NzContext* currentContext = nullptr;
NAZARA_THREADLOCAL NzContext* threadContext = nullptr;
std::vector<NzContext*> contexts;
void CALLBACK DebugCallback(unsigned int source, unsigned int type, unsigned int id, unsigned int severity, int length, const char* message, void* userParam)
{
@@ -269,7 +271,36 @@ void NzContext::SwapBuffers()
m_impl->SwapBuffers();
}
const NzContext* NzContext::GetCurrent()
bool NzContext::EnsureContext()
{
if (!currentContext)
{
if (!threadContext)
{
NzContext* context = new NzContext;
if (!context->Create())
{
NazaraError("Failed to create context");
delete context;
return false;
}
contexts.push_back(context);
threadContext = context;
}
else if (!threadContext->SetActive(true))
{
NazaraError("Failed to active thread context");
return false;
}
}
return true;
}
NzContext* NzContext::GetCurrent()
{
return currentContext;
}
@@ -279,12 +310,14 @@ const NzContext* NzContext::GetReference()
return s_reference;
}
const NzContext* NzContext::GetThreadContext()
NzContext* NzContext::GetThreadContext()
{
EnsureContext();
return threadContext;
}
bool NzContext::InitializeReference()
bool NzContext::Initialize()
{
NzContextParameters parameters;
// parameters.compatibilityProfile = true;
@@ -299,11 +332,21 @@ bool NzContext::InitializeReference()
return false;
}
// Le contexte de référence doit rester désactivé pour le partage
s_reference->SetActive(false);
NzContextParameters::defaultShareContext = s_reference;
return true;
}
void NzContext::UninitializeReference()
void NzContext::Uninitialize()
{
for (NzContext* context : contexts)
delete context;
contexts.clear(); // On supprime tous les contextes créés
delete s_reference;
s_reference = nullptr;
}

View File

@@ -6,6 +6,7 @@
#include <Nazara/Renderer/GLSLShader.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/String.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Renderer/VertexDeclaration.hpp>
@@ -52,6 +53,14 @@ bool NzGLSLShader::Bind()
}
#endif
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return false;
}
#endif
glUseProgram(m_program);
for (auto it = m_textures.begin(); it != m_textures.end(); ++it)
@@ -66,6 +75,8 @@ bool NzGLSLShader::Bind()
bool NzGLSLShader::Compile()
{
NzContext::EnsureContext();
m_idCache.clear();
glLinkProgram(m_program);
@@ -104,6 +115,8 @@ bool NzGLSLShader::Compile()
bool NzGLSLShader::Create()
{
NzContext::EnsureContext();
m_program = glCreateProgram();
if (!m_program)
{
@@ -126,13 +139,13 @@ bool NzGLSLShader::Create()
for (int i = 0; i < nzShaderType_Count; ++i)
m_shaders[i] = 0;
m_textureFreeID = 0;
return true;
}
void NzGLSLShader::Destroy()
{
NzContext::EnsureContext();
for (GLuint shader : m_shaders)
if (shader)
glDeleteShader(shader);
@@ -153,6 +166,8 @@ nzShaderLanguage NzGLSLShader::GetLanguage() const
NzString NzGLSLShader::GetSourceCode(nzShaderType type) const
{
NzContext::EnsureContext();
NzString source;
GLint length;
@@ -172,6 +187,8 @@ GLint NzGLSLShader::GetUniformLocation(const NzString& name) const
GLint id;
if (it == m_idCache.end())
{
NzContext::EnsureContext();
id = glGetUniformLocation(m_program, name.GetConstBuffer());
m_idCache[name] = id;
}
@@ -188,6 +205,8 @@ bool NzGLSLShader::IsLoaded(nzShaderType type) const
bool NzGLSLShader::Load(nzShaderType type, const NzString& source)
{
NzContext::EnsureContext();
GLuint shader = glCreateShader(shaderType[type]);
if (!shader)
{
@@ -244,6 +263,8 @@ bool NzGLSLShader::Lock()
{
if (lockedLevel++ == 0)
{
NzContext::EnsureContext();
GLint previous;
glGetIntegerv(GL_CURRENT_PROGRAM, &previous);
@@ -258,54 +279,168 @@ bool NzGLSLShader::Lock()
bool NzGLSLShader::SendBoolean(const NzString& name, bool value)
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1i)
glProgramUniform1i(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendDouble(const NzString& name, double value)
{
Lock();
glUniform1d(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1d)
glProgramUniform1d(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1d(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendFloat(const NzString& name, float value)
{
Lock();
glUniform1f(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1f)
glProgramUniform1f(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1f(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendInteger(const NzString& name, int value)
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
if (glProgramUniform1i)
glProgramUniform1i(m_program, GetUniformLocation(name), value);
else
{
Lock();
glUniform1i(GetUniformLocation(name), value);
Unlock();
}
return true;
}
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4d& matrix)
{
Lock();
glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
if (glProgramUniformMatrix4dv)
glProgramUniformMatrix4dv(m_program, GetUniformLocation(name), 1, GL_FALSE, matrix);
else
{
Lock();
glUniformMatrix4dv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
}
return true;
}
bool NzGLSLShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
{
Lock();
glUniformMatrix4fv(GetUniformLocation(name), 1, GL_FALSE, matrix);
Unlock();
if (glProgramUniformMatrix4fv)
glProgramUniformMatrix4fv(m_program, GetUniformLocation(name), 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;
}
@@ -356,25 +491,48 @@ bool NzGLSLShader::SendTexture(const NzString& name, NzTexture* texture)
m_textures[location] = TextureSlot{unit, texture};
Lock();
glUniform1i(location, unit);
Unlock();
if (glProgramUniform1i)
glProgramUniform1i(m_program, location, unit);
else
{
Lock();
glUniform1i(location, unit);
Unlock();
}
return true;
}
void NzGLSLShader::Unbind()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glUseProgram(0);
}
void NzGLSLShader::Unlock()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
#if NAZARA_RENDERER_SAFE
if (lockedLevel == 0)
{
NazaraWarning("Unlock called on non-locked texture");
return;
}
#endif
if (--lockedLevel == 0 && lockedPrevious != m_program)
glUseProgram(lockedPrevious);

View File

@@ -42,6 +42,12 @@ class NzGLSLShader : public NzShaderImpl
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);
void Unbind();
@@ -58,7 +64,6 @@ class NzGLSLShader : public NzShaderImpl
std::map<GLint, TextureSlot> m_textures;
GLuint m_program;
GLuint m_shaders[nzShaderType_Count];
nzUInt8 m_textureFreeID;
NzShader* m_parent;
NzString m_log;
};

View File

@@ -5,6 +5,7 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/HardwareBuffer.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <cstring>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
@@ -12,17 +13,17 @@
namespace
{
GLenum bufferLock[] = {
GL_WRITE_ONLY, // nzBufferLock_DiscardAndWrite
GL_READ_ONLY, // nzBufferLock_ReadOnly
GL_READ_WRITE, // nzBufferLock_ReadWrite
GL_WRITE_ONLY // nzBufferLock_WriteOnly
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, // nzBufferLock_DiscardAndWrite
GL_MAP_READ_BIT, // nzBufferLock_ReadOnly
GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, // nzBufferLock_ReadWrite
GL_MAP_WRITE_BIT // nzBufferLock_WriteOnly
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[] = {
@@ -43,13 +44,13 @@ namespace
GL_STATIC_DRAW // nzBufferUsage_Static
};
typedef nzUInt8* (*LockRoutine)(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size);
typedef nzUInt8* (*LockRoutine)(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
nzUInt8* LockBuffer(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size)
nzUInt8* LockBuffer(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
{
NazaraUnused(size);
if (lock == nzBufferLock_DiscardAndWrite)
if (access == nzBufferAccess_DiscardAndWrite)
{
GLint size;
glGetBufferParameteriv(bufferTargetBinding[type], GL_BUFFER_SIZE, &size);
@@ -61,30 +62,30 @@ namespace
glBufferData(bufferTargetBinding[type], size, nullptr, usage);
}
void* ptr = glMapBuffer(bufferTarget[type], bufferLock[lock]);
void* ptr = glMapBuffer(bufferTarget[type], bufferLock[access]);
if (ptr)
return reinterpret_cast<nzUInt8*>(ptr) + offset;
else
return nullptr;
}
nzUInt8* LockBufferRange(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size)
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
{
return reinterpret_cast<nzUInt8*>(glMapBufferRange(bufferTarget[type], offset, size, bufferLockRange[lock]));
return reinterpret_cast<nzUInt8*>(glMapBufferRange(bufferTarget[type], offset, size, bufferLockRange[access]));
}
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size);
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size);
LockRoutine lockBuffer = LockBufferFirstRun;
LockRoutine mapBuffer = LockBufferFirstRun;
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferLock lock, unsigned int offset, unsigned int size)
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
{
if (glMapBufferRange)
lockBuffer = LockBufferRange;
mapBuffer = LockBufferRange;
else
lockBuffer = LockBuffer;
mapBuffer = LockBuffer;
return lockBuffer(type, lock, offset, size);
return mapBuffer(type, access, offset, size);
}
}
@@ -100,20 +101,24 @@ NzHardwareBuffer::~NzHardwareBuffer()
void NzHardwareBuffer::Bind()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBindBuffer(bufferTarget[m_type], m_buffer);
}
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
{
NzContext::EnsureContext();
m_buffer = 0;
glGenBuffers(1, &m_buffer);
if (!m_buffer)
{
NazaraError("Failed to create buffer");
return false;
}
GLint previous;
glGetIntegerv(bufferTargetBinding[m_type], &previous);
@@ -129,11 +134,15 @@ bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
void NzHardwareBuffer::Destroy()
{
NzContext::EnsureContext();
glDeleteBuffers(1, &m_buffer);
}
bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
{
NzContext::EnsureContext();
GLuint previous;
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
@@ -152,10 +161,10 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
}
else
{
nzUInt8* ptr = lockBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferLock_DiscardAndWrite : nzBufferLock_WriteOnly, offset, size);
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
if (!ptr)
{
NazaraError("Failed to lock buffer");
NazaraError("Failed to map buffer");
return false;
}
@@ -164,7 +173,7 @@ bool NzHardwareBuffer::Fill(const void* data, unsigned int offset, unsigned int
if (glUnmapBuffer(bufferTarget[m_type]) != GL_TRUE)
{
// Une erreur rare est survenue, nous devons réinitialiser le buffer
NazaraError("Failed to unlock buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
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()]);
@@ -189,8 +198,10 @@ bool NzHardwareBuffer::IsHardware() const
return true;
}
void* NzHardwareBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length)
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
NzContext::EnsureContext();
// 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));
@@ -198,7 +209,7 @@ void* NzHardwareBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned in
if (previous != m_buffer)
glBindBuffer(bufferTarget[m_type], m_buffer);
void* ptr = lockBuffer(m_type, lock, offset, length);
void* ptr = mapBuffer(m_type, access, offset, length);
// Inutile de rebinder s'il n'y avait aucun buffer (Optimise les opérrations chaînées)
if (previous != m_buffer && previous != 0)
@@ -207,8 +218,10 @@ void* NzHardwareBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned in
return ptr;
}
bool NzHardwareBuffer::Unlock()
bool NzHardwareBuffer::Unmap()
{
NzContext::EnsureContext();
GLuint previous;
glGetIntegerv(bufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
@@ -218,7 +231,7 @@ bool NzHardwareBuffer::Unlock()
if (glUnmapBuffer(bufferTarget[m_type]) != GL_TRUE)
{
// Une erreur rare est survenue, nous devons réinitialiser le buffer
NazaraError("Failed to unlock buffer, reinitialising content... (OpenGL error : 0x" + NzString::Number(glGetError(), 16) + ')');
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()]);

View File

@@ -28,8 +28,8 @@ class NzHardwareBuffer : public NzBufferImpl
bool IsHardware() const;
void* Lock(nzBufferLock lock, unsigned int offset = 0, unsigned int length = 0);
bool Unlock();
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
bool Unmap();
private:
GLuint m_buffer;

View File

@@ -172,12 +172,12 @@ bool NzIndexBuffer::IsSequential() const
return m_buffer == nullptr;
}
void* NzIndexBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length)
void* NzIndexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_RENDERER_SAFE
if (!m_buffer)
{
NazaraError("Impossible to lock sequential index buffer");
NazaraError("Impossible to map sequential index buffer");
return nullptr;
}
@@ -188,10 +188,10 @@ void* NzIndexBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int l
}
#endif
return m_buffer->Lock(lock, m_startIndex+offset, (length) ? length : m_indexCount-offset);
return m_buffer->Map(access, m_startIndex+offset, (length) ? length : m_indexCount-offset);
}
bool NzIndexBuffer::Unlock()
bool NzIndexBuffer::Unmap()
{
#if NAZARA_RENDERER_SAFE
if (!m_buffer)
@@ -201,5 +201,5 @@ bool NzIndexBuffer::Unlock()
}
#endif
return m_buffer->Unlock();
return m_buffer->Unmap();
}

View File

@@ -6,6 +6,7 @@
#include <Nazara/Renderer/OcclusionQuery.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
@@ -15,9 +16,13 @@ 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");
@@ -38,6 +43,8 @@ NzOcclusionQuery::~NzOcclusionQuery()
{
if (m_id)
{
NzContext::EnsureContext();
GLuint query = static_cast<GLuint>(m_id);
glDeleteQueries(1, &query);
}
@@ -45,16 +52,34 @@ NzOcclusionQuery::~NzOcclusionQuery()
void NzOcclusionQuery::Begin()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBeginQuery(GL_SAMPLES_PASSED, m_id);
}
void NzOcclusionQuery::End()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glEndQuery(GL_SAMPLES_PASSED);
}
unsigned int NzOcclusionQuery::GetResult() const
{
NzContext::EnsureContext();
GLuint result;
glGetQueryObjectuiv(m_id, GL_QUERY_RESULT, &result);
@@ -63,6 +88,8 @@ unsigned int NzOcclusionQuery::GetResult() const
bool NzOcclusionQuery::IsResultAvailable() const
{
NzContext::EnsureContext();
GLint available;
glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available);

View File

@@ -116,7 +116,6 @@ bool NzOpenGL::Initialize()
}
// Le chargement des fonctions OpenGL nécessite un contexte OpenGL
// Le contexte de chargement ne peut pas être partagé car le contexte de référence n'existe pas encore
NzContextParameters parameters;
parameters.majorVersion = 2;
parameters.minorVersion = 0;
@@ -124,8 +123,8 @@ bool NzOpenGL::Initialize()
/*
Note: Même le contexte de chargement nécessite quelques fonctions de base pour correctement s'initialiser
Pour cette raison, sa création est faite en deux fois, la première sert à récupérer le strict minimum,
la seconde à créer le véritable contexte de chargement.
Pour cette raison, deux contextes sont créés, le premier sert à récupérer les fonctions permetttant
de créer le second avec les bons paramètres.s
Non sérieusement si quelqu'un a une meilleure idée qu'il me le dise
*/
@@ -371,50 +370,50 @@ bool NzOpenGL::Initialize()
}
// FrameBufferObject
try
if (openGLversion >= 300 || IsSupported("GL_ARB_framebuffer_object"))
{
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(LoadEntry("glBindFramebuffer"));
glBindRenderbuffer = reinterpret_cast<PFNGLBINDRENDERBUFFERPROC>(LoadEntry("glBindRenderbuffer"));
glCheckFramebufferStatus = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSPROC>(LoadEntry("glCheckFramebufferStatus"));
glDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(LoadEntry("glDeleteFramebuffers"));
glDeleteRenderbuffers = reinterpret_cast<PFNGLDELETERENDERBUFFERSPROC>(LoadEntry("glDeleteRenderbuffers"));
glFramebufferRenderbuffer = reinterpret_cast<PFNGLFRAMEBUFFERRENDERBUFFERPROC>(LoadEntry("glFramebufferRenderbuffer"));
glFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(LoadEntry("glFramebufferTexture2D"));
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPPROC>(LoadEntry("glGenerateMipmap"));
glGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(LoadEntry("glGenFramebuffers"));
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSPROC>(LoadEntry("glGenRenderbuffers"));
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEPROC>(LoadEntry("glRenderbufferStorage"));
openGLextensions[NzOpenGL::FrameBufferObject] = true;
}
catch (const std::exception& e)
{
if (openGLversion >= 300)
NazaraWarning("Failed to load core FBOs (" + NzString(e.what()) + ")");
if (IsSupported("GL_EXT_framebuffer_object"))
try
{
try
{
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFEREXTPROC>(LoadEntry("glBindFramebufferEXT"));
glBindRenderbuffer = reinterpret_cast<PFNGLBINDRENDERBUFFEREXTPROC>(LoadEntry("glBindRenderbufferEXT"));
glCheckFramebufferStatus = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC>(LoadEntry("glCheckFramebufferStatusEXT"));
glDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSEXTPROC>(LoadEntry("glDeleteFramebuffersEXT"));
glDeleteRenderbuffers = reinterpret_cast<PFNGLDELETERENDERBUFFERSEXTPROC>(LoadEntry("glDeleteRenderbuffersEXT"));
glFramebufferRenderbuffer = reinterpret_cast<PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC>(LoadEntry("glFramebufferRenderbufferEXT"));
glFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DEXTPROC>(LoadEntry("glFramebufferTexture2DEXT"));
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPEXTPROC>(LoadEntry("glGenerateMipmapEXT"));
glGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSEXTPROC>(LoadEntry("glGenFramebuffersEXT"));
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSEXTPROC>(LoadEntry("glGenRenderbuffersEXT"));
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEEXTPROC>(LoadEntry("glRenderbufferStorageEXT"));
glBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(LoadEntry("glBindFramebuffer"));
glBindRenderbuffer = reinterpret_cast<PFNGLBINDRENDERBUFFERPROC>(LoadEntry("glBindRenderbuffer"));
glCheckFramebufferStatus = reinterpret_cast<PFNGLCHECKFRAMEBUFFERSTATUSPROC>(LoadEntry("glCheckFramebufferStatus"));
glDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(LoadEntry("glDeleteFramebuffers"));
glDeleteRenderbuffers = reinterpret_cast<PFNGLDELETERENDERBUFFERSPROC>(LoadEntry("glDeleteRenderbuffers"));
glFramebufferRenderbuffer = reinterpret_cast<PFNGLFRAMEBUFFERRENDERBUFFERPROC>(LoadEntry("glFramebufferRenderbuffer"));
glFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(LoadEntry("glFramebufferTexture2D"));
glGenerateMipmap = reinterpret_cast<PFNGLGENERATEMIPMAPPROC>(LoadEntry("glGenerateMipmap"));
glGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(LoadEntry("glGenFramebuffers"));
glGenRenderbuffers = reinterpret_cast<PFNGLGENRENDERBUFFERSPROC>(LoadEntry("glGenRenderbuffers"));
glRenderbufferStorage = reinterpret_cast<PFNGLRENDERBUFFERSTORAGEPROC>(LoadEntry("glRenderbufferStorage"));
openGLextensions[NzOpenGL::FrameBufferObject] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load EXT_framebuffer_object: " + NzString(e.what()));
}
openGLextensions[NzOpenGL::FrameBufferObject] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load ARB_framebuffer_object: (" + NzString(e.what()) + ")");
}
}
// SeparateShaderObjects
if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64"))
{
glProgramUniform1f = reinterpret_cast<PFNGLPROGRAMUNIFORM1FPROC>(LoadEntry("glProgramUniform1f"));
glProgramUniform1i = reinterpret_cast<PFNGLPROGRAMUNIFORM1IPROC>(LoadEntry("glProgramUniform1i"));
glProgramUniform2fv = reinterpret_cast<PFNGLPROGRAMUNIFORM2FVPROC>(LoadEntry("glProgramUniform2fv"));
glProgramUniform3fv = reinterpret_cast<PFNGLPROGRAMUNIFORM3FVPROC>(LoadEntry("glProgramUniform3fv"));
glProgramUniform4fv = reinterpret_cast<PFNGLPROGRAMUNIFORM4FVPROC>(LoadEntry("glProgramUniform4fv"));
glProgramUniformMatrix4fv = reinterpret_cast<PFNGLPROGRAMUNIFORMMATRIX4FVPROC>(LoadEntry("glProgramUniformMatrix4fv"));
if (openGLextensions[NzOpenGL::FP64])
{
glProgramUniform1d = reinterpret_cast<PFNGLPROGRAMUNIFORM1DPROC>(LoadEntry("glProgramUniform1d"));
glProgramUniform2dv = reinterpret_cast<PFNGLPROGRAMUNIFORM2DVPROC>(LoadEntry("glProgramUniform2dv"));
glProgramUniform3dv = reinterpret_cast<PFNGLPROGRAMUNIFORM3DVPROC>(LoadEntry("glProgramUniform3dv"));
glProgramUniform4dv = reinterpret_cast<PFNGLPROGRAMUNIFORM4DVPROC>(LoadEntry("glProgramUniform4dv"));
glProgramUniformMatrix4dv = reinterpret_cast<PFNGLPROGRAMUNIFORMMATRIX4DVPROC>(LoadEntry("glProgramUniformMatrix4dv"));
}
openGLextensions[NzOpenGL::SeparateShaderObjects] = true;
}
// Texture3D
@@ -452,7 +451,7 @@ bool NzOpenGL::Initialize()
// TextureCompression_s3tc
openGLextensions[NzOpenGL::TextureCompression_s3tc] = IsSupported("GL_EXT_texture_compression_s3tc");
// VertexArrayObject
// TextureStorage
if (openGLversion >= 420 || IsSupported("GL_ARB_texture_storage"))
{
try
@@ -489,16 +488,14 @@ bool NzOpenGL::Initialize()
/****************************************Contexte de référence****************************************/
///FIXME: Utiliser le contexte de chargement comme référence ? (Vérifier mode debug)
if (!NzContext::InitializeReference())
if (!NzContext::Initialize())
{
NazaraError("Failed to initialize reference context");
NazaraError("Failed to initialize contexts");
Uninitialize();
return false;
}
NzContextParameters::defaultShareContext = NzContext::GetReference();
return true;
}
@@ -514,7 +511,7 @@ bool NzOpenGL::IsSupported(const NzString& string)
void NzOpenGL::Uninitialize()
{
NzContext::UninitializeReference();
NzContext::Uninitialize();
for (bool& ext : openGLextensions)
ext = false;
@@ -604,6 +601,17 @@ PFNGLLINKPROGRAMPROC glLinkProgram = nullptr;
PFNGLMAPBUFFERPROC glMapBuffer = nullptr;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr;
PFNGLPOLYGONMODEPROC glPolygonMode = nullptr;
PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr;
PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr;
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = nullptr;
PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv = nullptr;
PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv = nullptr;
PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv = nullptr;
PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv = nullptr;
PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv = nullptr;
PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv = nullptr;
PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv = nullptr;
PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv = nullptr;
PFNGLREADPIXELSPROC glReadPixels = nullptr;
PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = nullptr;
PFNGLSCISSORPROC glScissor = nullptr;

View File

@@ -25,5 +25,5 @@ bool NzRenderTarget::SetActive(bool active)
void NzRenderTarget::Desactivate()
{
// Seuls les target sans contextes (ex: RenderTexture) nécessitent une désactivation
// Seuls les target sans contextes (ex: NzRenderTexture) nécessitent une désactivation
}

View File

@@ -5,9 +5,7 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/RenderWindow.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/ContextParameters.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
@@ -49,11 +47,6 @@ NzRenderWindow::~NzRenderWindow()
{
}
bool NzRenderWindow::CanActivate() const
{
return m_impl != nullptr && m_context != nullptr;
}
bool NzRenderWindow::CopyToImage(NzImage* image)
{
#if NAZARA_RENDERER_SAFE
@@ -144,7 +137,7 @@ bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& pa
void NzRenderWindow::Display()
{
if (m_context)
if (m_context && m_parameters.doubleBuffered)
m_context->SwapBuffers();
}
@@ -181,7 +174,23 @@ void NzRenderWindow::EnableVerticalSync(bool enabled)
NazaraError("No context");
}
NzRenderTargetParameters NzRenderWindow::GetRenderTargetParameters() const
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();
}
NzRenderTargetParameters NzRenderWindow::GetParameters() const
{
if (m_context)
{
@@ -195,15 +204,9 @@ NzRenderTargetParameters NzRenderWindow::GetRenderTargetParameters() const
}
}
NzContextParameters NzRenderWindow::GetContextParameters() const
unsigned int NzRenderWindow::GetWidth() const
{
if (m_context)
return m_context->GetParameters();
else
{
NazaraError("Window not created/context not initialized");
return NzContextParameters();
}
return NzWindow::GetWidth();
}
bool NzRenderWindow::HasContext() const
@@ -211,9 +214,23 @@ bool NzRenderWindow::HasContext() const
return true;
}
bool NzRenderWindow::IsValid() const
{
return m_impl != nullptr && m_context != nullptr;
}
bool NzRenderWindow::Activate()
{
return m_context->SetActive(true);
if (m_context->SetActive(true))
{
glDrawBuffer((m_parameters.doubleBuffered) ? GL_BACK : GL_FRONT);
return true;
}
else
{
NazaraError("Failed to activate window's context");
return false;
}
}
void NzRenderWindow::OnClose()

View File

@@ -23,17 +23,32 @@ namespace
{
const nzUInt8 attribIndex[] =
{
2, // nzElementUsage_Diffuse
1, // nzElementUsage_Normal
0, // nzElementUsage_Position
3, // nzElementUsage_Tangent
4 // nzElementUsage_TexCoord
2, // nzElementUsage_Diffuse
1, // nzElementUsage_Normal
0, // nzElementUsage_Position
3, // nzElementUsage_Tangent
4 // nzElementUsage_TexCoord
};
const GLenum blendFunc[] =
{
GL_DST_ALPHA, // nzBlendFunc_DestAlpha
GL_DST_COLOR, // nzBlendFunc_DestColor
GL_SRC_ALPHA, // nzBlendFunc_SrcAlpha
GL_SRC_COLOR, // nzBlendFunc_SrcColor
GL_ONE_MINUS_DST_ALPHA, // nzBlendFunc_InvDestAlpha
GL_ONE_MINUS_DST_COLOR, // nzBlendFunc_InvDestColor
GL_ONE_MINUS_SRC_ALPHA, // nzBlendFunc_InvSrcAlpha
GL_ONE_MINUS_SRC_COLOR, // nzBlendFunc_InvSrcColor
GL_ONE, // nzBlendFunc_One
GL_ZERO // nzBlendFunc_Zero
};
const GLenum faceCullingMode[] =
{
GL_BACK, // nzFaceCulling_Back
GL_FRONT, // nzFaceCulling_Front
GL_BACK, // nzFaceCulling_Back
GL_FRONT, // nzFaceCulling_Front
GL_FRONT_AND_BACK // nzFaceCulling_FrontAndBack
};
@@ -41,18 +56,18 @@ namespace
{
GL_POINT, // nzFaceFilling_Point
GL_LINE, // nzFaceFilling_Line
GL_FILL // nzFaceFilling_Fill
GL_FILL // nzFaceFilling_Fill
};
const GLenum openglPrimitive[] =
{
GL_LINES, // nzPrimitiveType_LineList,
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
GL_POINTS, // nzPrimitiveType_PointList,
GL_TRIANGLES, // nzPrimitiveType_TriangleList,
GL_LINES, // nzPrimitiveType_LineList,
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
GL_POINTS, // nzPrimitiveType_PointList,
GL_TRIANGLES, // nzPrimitiveType_TriangleList,
GL_TRIANGLE_STRIP, // nzPrimitiveType_TriangleStrip,
GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan
GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan
};
const nzUInt8 openglSize[] =
@@ -71,47 +86,47 @@ namespace
const GLenum openglType[] =
{
GL_UNSIGNED_BYTE, // nzElementType_Color
GL_DOUBLE, // nzElementType_Double1
GL_DOUBLE, // nzElementType_Double2
GL_DOUBLE, // nzElementType_Double3
GL_DOUBLE, // nzElementType_Double4
GL_FLOAT, // nzElementType_Float1
GL_FLOAT, // nzElementType_Float2
GL_FLOAT, // nzElementType_Float3
GL_FLOAT // nzElementType_Float4
GL_DOUBLE, // nzElementType_Double1
GL_DOUBLE, // nzElementType_Double2
GL_DOUBLE, // nzElementType_Double3
GL_DOUBLE, // nzElementType_Double4
GL_FLOAT, // nzElementType_Float1
GL_FLOAT, // nzElementType_Float2
GL_FLOAT, // nzElementType_Float3
GL_FLOAT // nzElementType_Float4
};
const GLenum rendererComparison[] =
{
GL_ALWAYS, // nzRendererComparison_Always
GL_EQUAL, // nzRendererComparison_Equal
GL_GREATER, // nzRendererComparison_Greater
GL_GEQUAL, // nzRendererComparison_GreaterOrEqual
GL_LESS, // nzRendererComparison_Less
GL_LEQUAL, // nzRendererComparison_LessOrEqual
GL_NEVER // nzRendererComparison_Never
GL_ALWAYS, // nzRendererComparison_Always
GL_EQUAL, // nzRendererComparison_Equal
GL_GREATER, // nzRendererComparison_Greater
GL_GEQUAL, // nzRendererComparison_GreaterOrEqual
GL_LESS, // nzRendererComparison_Less
GL_LEQUAL, // nzRendererComparison_LessOrEqual
GL_NEVER // nzRendererComparison_Never
};
const GLenum rendererParameter[] =
{
GL_BLEND, // nzRendererParameter_Blend
GL_NONE, // nzRendererParameter_ColorWrite
GL_DEPTH_TEST, // nzRendererParameter_DepthTest
GL_NONE, // nzRendererParameter_DepthWrite
GL_CULL_FACE, // nzRendererParameter_FaceCulling
GL_STENCIL_TEST // nzRendererParameter_Stencil
GL_BLEND, // nzRendererParameter_Blend
GL_NONE, // nzRendererParameter_ColorWrite
GL_DEPTH_TEST, // nzRendererParameter_DepthTest
GL_NONE, // nzRendererParameter_DepthWrite
GL_CULL_FACE, // nzRendererParameter_FaceCulling
GL_STENCIL_TEST // nzRendererParameter_Stencil
};
const GLenum stencilOperation[] =
{
GL_DECR, // nzStencilOperation_Decrement
GL_DECR, // nzStencilOperation_Decrement
GL_DECR_WRAP, // nzStencilOperation_DecrementToSaturation
GL_INCR, // nzStencilOperation_Increment
GL_INCR, // nzStencilOperation_Increment
GL_INCR_WRAP, // nzStencilOperation_IncrementToSaturation
GL_INVERT, // nzStencilOperation_Invert
GL_KEEP, // nzStencilOperation_Keep
GL_REPLACE, // nzStencilOperation_Replace
GL_ZERO // nzStencilOperation_Zero
GL_INVERT, // nzStencilOperation_Invert
GL_KEEP, // nzStencilOperation_Keep
GL_REPLACE, // nzStencilOperation_Replace
GL_ZERO // nzStencilOperation_Zero
};
}
@@ -228,6 +243,14 @@ void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVer
void NzRenderer::Enable(nzRendererParameter parameter, bool enable)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
switch (parameter)
{
case nzRendererParameter_ColorWrite:
@@ -273,6 +296,22 @@ NzRenderTarget* NzRenderer::GetTarget() const
return m_target;
}
NzRectui NzRenderer::GetViewport() const
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return NzRectui();
}
#endif
GLint params[4];
glGetIntegerv(GL_VIEWPORT, &params[0]);
return NzRectui(params[0], params[1], params[2], params[3]);
}
bool NzRenderer::HasCapability(nzRendererCap capability) const
{
return m_capabilities[capability];
@@ -297,6 +336,11 @@ bool NzRenderer::Initialize()
if (NzOpenGL::Initialize())
{
NzContext::EnsureContext();
const NzContext* context = NzContext::GetReference();
bool compatibility = context->GetParameters().compatibilityProfile;
m_vaoUpdated = false;
m_indexBuffer = nullptr;
m_shader = nullptr;
@@ -318,7 +362,7 @@ bool NzRenderer::Initialize()
m_capabilities[nzRendererCap_HardwareBuffer] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_MultipleRenderTargets] = true; // Natif depuis OpenGL 2.0
m_capabilities[nzRendererCap_OcclusionQuery] = true; // Natif depuis OpenGL 1.5
m_capabilities[nzRendererCap_SoftwareBuffer] = NzOpenGL::GetVersion() <= 300; // Déprécié en OpenGL 3
m_capabilities[nzRendererCap_SoftwareBuffer] = compatibility || NzOpenGL::GetVersion() <= 300; // Déprécié en OpenGL 3
m_capabilities[nzRendererCap_Texture3D] = NzOpenGL::IsSupported(NzOpenGL::Texture3D);
m_capabilities[nzRendererCap_TextureCubemap] = true; // Natif depuis OpenGL 1.3
m_capabilities[nzRendererCap_TextureMulti] = true; // Natif depuis OpenGL 1.3
@@ -336,14 +380,10 @@ bool NzRenderer::Initialize()
if (m_capabilities[nzRendererCap_MultipleRenderTargets])
{
// Permettre de gérer plus de targets que de nombre de sorties dans le shader ne servirait à rien
GLint maxDrawBuffers;
glGetIntegerv(GL_MAX_DRAW_BUFFERS, &maxDrawBuffers);
GLint maxRenderTextureTargets;
glGetIntegerv(GL_MAX_COLOR_ATTACHMENTS, &maxRenderTextureTargets);
m_maxRenderTarget = static_cast<unsigned int>(std::min(maxDrawBuffers, maxRenderTextureTargets));
m_maxRenderTarget = static_cast<unsigned int>(maxDrawBuffers);
}
else
m_maxRenderTarget = 1;
@@ -366,6 +406,19 @@ bool NzRenderer::Initialize()
return false;
}
void NzRenderer::SetBlendFunc(nzBlendFunc src, nzBlendFunc dest)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBlendFunc(blendFunc[src], blendFunc[dest]);
}
void NzRenderer::SetClearColor(const NzColor& color)
{
#ifdef NAZARA_DEBUG
@@ -462,10 +515,7 @@ bool NzRenderer::SetShader(NzShader* shader)
return true;
if (m_shader)
{
m_shader->m_impl->Unbind();
m_shader = nullptr;
}
if (shader)
{
@@ -473,6 +523,8 @@ bool NzRenderer::SetShader(NzShader* shader)
if (!shader->IsCompiled())
{
NazaraError("Shader is not compiled");
m_shader = nullptr;
return false;
}
#endif
@@ -480,9 +532,13 @@ bool NzRenderer::SetShader(NzShader* shader)
if (!shader->m_impl->Bind())
{
NazaraError("Failed to bind shader");
m_shader = nullptr;
return false;
}
}
else
m_shader = nullptr;
m_shader = shader;
@@ -548,19 +604,19 @@ bool NzRenderer::SetTarget(NzRenderTarget* target)
if (target == m_target)
return true;
#if NAZARA_RENDERER_SAFE
if (target && !target->CanActivate())
{
NazaraError("Target cannot be activated");
return false;
}
#endif
if (m_target && !m_target->HasContext())
m_target->Desactivate();
if (target)
{
#if NAZARA_RENDERER_SAFE
if (!target->IsValid())
{
NazaraError("Target not valid");
return false;
}
#endif
if (target->Activate())
m_target = target;
else
@@ -599,6 +655,43 @@ bool NzRenderer::SetVertexDeclaration(const NzVertexDeclaration* vertexDeclarati
return true;
}
void NzRenderer::SetViewport(const NzRectui& viewport)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
unsigned int height = m_target->GetHeight();
#if NAZARA_RENDERER_SAFE
if (!m_target)
{
NazaraError("Renderer has no target");
return;
}
unsigned int width = m_target->GetWidth();
if (viewport.x+viewport.width >= width)
{
NazaraError("Rectangle dimensions are out of bounds");
return;
}
if (viewport.y+viewport.height >= height)
{
NazaraError("Rectangle dimensions are out of bounds");
return;
}
#endif
glViewport(viewport.x, height-viewport.height-viewport.y, viewport.width, viewport.height);
glScissor(viewport.x, height-viewport.height-viewport.y, viewport.width, viewport.height);
}
void NzRenderer::Uninitialize()
{
#if NAZARA_RENDERER_SAFE
@@ -609,6 +702,8 @@ void NzRenderer::Uninitialize()
}
#endif
NzContext::EnsureContext();
s_initialized = false;
// Libération des VAOs
@@ -644,6 +739,14 @@ bool NzRenderer::IsInitialized()
bool NzRenderer::EnsureStateUpdate()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return false;
}
#endif
if (!m_stencilFuncUpdated)
{
glStencilFunc(rendererComparison[m_stencilCompare], m_stencilReference, m_stencilMask);

View File

@@ -253,11 +253,12 @@ bool NzShader::LoadFromFile(nzShaderType type, const NzString& filePath)
return false;
}
NzString source;
unsigned int length = file.GetSize();
NzString source;
source.Resize(length);
if (file.Read(&source[0], sizeof(char), length) != length*sizeof(char))
if (file.Read(&source[0], length) != length)
{
NazaraError("Failed to read shader file");
return false;
@@ -371,6 +372,102 @@ bool NzShader::SendMatrix(const NzString& name, const NzMatrix4f& matrix)
return m_impl->SendMatrix(name, matrix);
}
bool NzShader::SendVector(const NzString& name, const NzVector2d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (!NazaraRenderer->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;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector3d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (!NazaraRenderer->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;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector4d& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
NazaraError("Shader not created");
return false;
}
if (!NazaraRenderer->HasCapability(nzRendererCap_FP64))
{
NazaraError("FP64 is not supported");
return false;
}
#endif
return m_impl->SendVector(name, vector);
}
bool NzShader::SendVector(const NzString& name, const NzVector4f& vector)
{
#if NAZARA_RENDERER_SAFE
if (!m_impl)
{
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

View File

@@ -45,6 +45,12 @@ class NzShaderImpl
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 void Unbind() = 0;

View File

@@ -6,6 +6,7 @@
#include <Nazara/Renderer/SoftwareBuffer.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <cstring>
#include <stdexcept>
#include <Nazara/Renderer/Debug.hpp>
@@ -30,6 +31,14 @@ NzSoftwareBuffer::~NzSoftwareBuffer()
void NzSoftwareBuffer::Bind()
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
glBindBuffer(bufferTarget[m_type], 0);
}
@@ -48,7 +57,7 @@ bool NzSoftwareBuffer::Create(unsigned int size, nzBufferUsage usage)
return false;
}
m_locked = false;
m_mapped = false;
return true;
}
@@ -61,9 +70,9 @@ void NzSoftwareBuffer::Destroy()
bool NzSoftwareBuffer::Fill(const void* data, unsigned int offset, unsigned int size)
{
#if NAZARA_RENDERER_SAFE
if (m_locked)
if (m_mapped)
{
NazaraError("Buffer already locked");
NazaraError("Buffer already mapped");
return false;
}
#endif
@@ -83,35 +92,35 @@ bool NzSoftwareBuffer::IsHardware() const
return false;
}
void* NzSoftwareBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int size)
void* NzSoftwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
{
NazaraUnused(lock);
NazaraUnused(access);
NazaraUnused(size);
#if NAZARA_RENDERER_SAFE
if (m_locked)
if (m_mapped)
{
NazaraError("Buffer already locked");
NazaraError("Buffer already mapped");
return nullptr;
}
#endif
m_locked = true;
m_mapped = true;
return &m_buffer[offset];
}
bool NzSoftwareBuffer::Unlock()
bool NzSoftwareBuffer::Unmap()
{
#if NAZARA_RENDERER_SAFE
if (!m_locked)
if (!m_mapped)
{
NazaraError("Buffer not locked");
NazaraError("Buffer not mapped");
return true;
}
#endif
m_locked = false;
m_mapped = false;
return true;
}

View File

@@ -27,13 +27,13 @@ class NzSoftwareBuffer : public NzBufferImpl
bool IsHardware() const;
void* Lock(nzBufferLock lock, unsigned int offset = 0, unsigned int length = 0);
bool Unlock();
void* Map(nzBufferAccess access, unsigned int offset = 0, unsigned int length = 0);
bool Unmap();
private:
nzBufferType m_type;
nzUInt8* m_buffer;
bool m_locked;
bool m_mapped;
};
#endif // NAZARA_SOFTWAREBUFFER_HPP

View File

@@ -5,6 +5,7 @@
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/Texture.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Renderer.hpp>
#include <Nazara/Renderer/RenderWindow.hpp>
#include <stdexcept>
@@ -14,8 +15,9 @@ struct NzTextureImpl
{
// GCC 4.7 !!!!!!
NzTextureImpl() :
isTarget(false),
mipmapping(false),
mipmapsUpdated(false)
mipmapsUpdated(true)
{
}
@@ -23,6 +25,7 @@ struct NzTextureImpl
nzImageType type;
nzPixelFormat format;
nzUInt8 levelCount;
bool isTarget;
bool mipmapping;
bool mipmapsUpdated;
unsigned int depth;
@@ -73,31 +76,31 @@ namespace
format->dataFormat = GL_BGR;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGB8;
break;
return true;
case nzPixelFormat_BGRA8:
format->dataFormat = GL_BGRA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGBA8;
break;
return true;
case nzPixelFormat_DXT1:
format->dataFormat = GL_RGB;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT;
break;
return true;
case nzPixelFormat_DXT3:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT;
break;
return true;
case nzPixelFormat_DXT5:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT;
break;
return true;
case nzPixelFormat_L8:
case nzPixelFormat_LA8:
@@ -108,32 +111,35 @@ namespace
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_SHORT_5_5_5_1;
format->internalFormat = GL_RGB5_A1;
break;
return true;
case nzPixelFormat_RGB8:
format->dataFormat = GL_RGB;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGB8;
break;
return true;
case nzPixelFormat_RGBA4:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_SHORT_4_4_4_4;
format->internalFormat = GL_RGBA4;
break;
return true;
case nzPixelFormat_RGBA8:
format->dataFormat = GL_RGBA;
format->dataType = GL_UNSIGNED_BYTE;
format->internalFormat = GL_RGBA8;
break;
return true;
default:
NazaraError("Pixel format not handled");
case nzPixelFormat_Undefined:
case nzPixelFormat_Count:
NazaraInternalError("Invalid pixel format");
return false;
}
return true;
NazaraError("Pixel format not handled");
return false;
}
bool CreateTexture(NzTextureImpl* impl, bool proxy)
@@ -145,8 +151,6 @@ namespace
return false;
}
static const bool texStorageSupported = NzOpenGL::IsSupported(NzOpenGL::TextureStorage);
GLenum target;
switch (impl->type)
{
@@ -154,15 +158,16 @@ namespace
{
target = (proxy) ? GL_TEXTURE_1D : GL_PROXY_TEXTURE_1D;
if (texStorageSupported)
/*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)
{
glTexImage1D(target, level, openGLFormat.internalFormat, w, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
w = std::max(w/2, 1U);
if (w > 1U)
w >>= 1;
}
}
break;
@@ -172,17 +177,20 @@ namespace
{
target = (proxy) ? GL_TEXTURE_2D : GL_PROXY_TEXTURE_2D;
if (texStorageSupported)
/*if (glTexStorage2D)
glTexStorage2D(target, impl->levelCount, openGLFormat.internalFormat, impl->width, impl->height);
else
else*/
{
unsigned int w = impl->width;
unsigned int h = impl->height;
for (nzUInt8 level = 0; level < impl->levelCount; ++level)
{
glTexImage2D(target, level, openGLFormat.internalFormat, w, h, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
w = std::max(w/2, 1U);
h = std::max(h/2, 1U);
if (w > 1U)
w >>= 1;
if (h > 1U)
h >>= 1;
}
}
break;
@@ -192,9 +200,9 @@ namespace
{
target = (proxy) ? GL_TEXTURE_3D : GL_PROXY_TEXTURE_3D;
if (texStorageSupported)
/*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;
@@ -202,9 +210,14 @@ namespace
for (nzUInt8 level = 0; level < impl->levelCount; ++level)
{
glTexImage3D(target, level, openGLFormat.internalFormat, w, h, d, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
w = std::max(w/2, 1U);
h = std::max(h/2, 1U);
d = std::max(d/2, 1U);
if (w > 1U)
w >>= 1;
if (h > 1U)
h >>= 1;
if (d > 1U)
d >>= 1;
}
}
break;
@@ -214,9 +227,9 @@ namespace
{
target = (proxy) ? GL_TEXTURE_CUBE_MAP : GL_PROXY_TEXTURE_CUBE_MAP;
if (texStorageSupported)
/*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)
@@ -224,7 +237,8 @@ namespace
for (GLenum face : cubemapFace)
glTexImage2D(face, level, openGLFormat.internalFormat, size, size, 0, openGLFormat.dataFormat, openGLFormat.dataType, nullptr);
size = std::max(size/2, 1U);
if (size > 1U)
size >>= 1;
}
}
break;
@@ -253,6 +267,8 @@ namespace
{
if (lockedLevel[impl->type]++ == 0)
{
NzContext::EnsureContext();
GLint previous;
glGetIntegerv(openglTargetBinding[impl->type], &previous);
@@ -265,6 +281,14 @@ namespace
void UnlockTexture(NzTextureImpl* impl)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
#if NAZARA_RENDERER_SAFE
if (lockedLevel[impl->type] == 0)
{
@@ -302,7 +326,7 @@ NzTexture::~NzTexture()
Destroy();
}
bool NzTexture::Bind()
bool NzTexture::Bind() const
{
#if NAZARA_RENDERER_SAFE
if (lockedLevel[m_impl->type] > 0)
@@ -314,11 +338,25 @@ bool NzTexture::Bind()
glBindTexture(openglTarget[m_impl->type], m_impl->id);
if (!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)
@@ -348,7 +386,7 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
case nzImageType_1D:
if (height > 1)
{
NazaraError("1D textures must be 1 height");
NazaraError("One dimensional texture's height must be 1");
return false;
}
@@ -390,6 +428,8 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
}
#endif
NzContext::EnsureContext();
levelCount = std::min(levelCount, NzImage::GetMaxLevel(width, height, depth));
NzTextureImpl* impl = new NzTextureImpl;
@@ -433,6 +473,12 @@ bool NzTexture::Create(nzImageType type, nzPixelFormat format, unsigned int widt
SetMipmapRange(0, m_impl->levelCount);
SetWrapMode(nzTextureWrap_Repeat);
if (m_impl->levelCount > 1U)
{
m_impl->mipmapping = true;
m_impl->mipmapsUpdated = false;
}
if (!lock)
UnlockTexture(impl);
@@ -443,6 +489,16 @@ 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
NzContext::EnsureContext();
glDeleteTextures(1, &m_impl->id);
delete m_impl;
m_impl = nullptr;
@@ -505,9 +561,14 @@ bool NzTexture::Download(NzImage* image) const
ptr += faceSize;
}
width = std::max(width >> 1, 1U);
height = std::max(height >> 1, 1U);
depth = std::max(depth >> 1, 1U);
if (width > 1)
width >>= 1;
if (height > 1)
height >>= 1;
if (depth > 1)
depth >>= 1;
}
UnlockTexture(m_impl);
@@ -533,15 +594,22 @@ bool NzTexture::EnableMipmapping(bool enable)
return false;
}
LockTexture(m_impl);
if (!m_impl->mipmapping && enable)
glGenerateMipmap(openglTarget[m_impl->type]);
{
GLint tex;
glGetIntegerv(openglTargetBinding[m_impl->type], &tex);
if (m_impl->id == static_cast<GLuint>(tex))
{
glGenerateMipmap(openglTarget[m_impl->type]);
m_impl->mipmapsUpdated = true;
}
else
m_impl->mipmapsUpdated = false;
}
m_impl->mipmapping = enable;
UnlockTexture(m_impl);
return true;
}
@@ -744,6 +812,19 @@ bool NzTexture::IsCubemap() const
return m_impl->type == nzImageType_Cubemap;
}
bool NzTexture::IsTarget() const
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
{
NazaraError("Texture must be valid");
return false;
}
#endif
return m_impl->isTarget;
}
bool NzTexture::IsValid() const
{
return m_impl != nullptr;
@@ -1059,7 +1140,7 @@ bool NzTexture::Update(const NzImage& image, const NzRectui& rect, unsigned int
return Update(image.GetConstPixels(level), rect, z, level);
}
/*
bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
@@ -1078,7 +1159,7 @@ bool NzTexture::Update(const NzImage& image, const NzCubeui& cube, nzUInt8 level
return Update(image.GetConstPixels(level), cube, level);
}
*/
bool NzTexture::Update(const nzUInt8* pixels, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
@@ -1090,11 +1171,7 @@ bool NzTexture::Update(const nzUInt8* pixels, nzUInt8 level)
#endif
if (m_impl->type == nzImageType_3D)
{
NazaraInternalError("Not implemented yet, sorry");
return false;
//return Update(pixels, NzCube(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);
}
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);
}
@@ -1108,6 +1185,12 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
return false;
}
if (m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
}
if (m_impl->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
@@ -1190,8 +1273,8 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int
return true;
}
/*
bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level = 0)
bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
@@ -1200,6 +1283,12 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
return false;
}
if (m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
}
if (m_impl->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
@@ -1263,15 +1352,15 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
switch (m_impl->type)
{
case nzImageType_1D:
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format->dataFormat, format->dataType, mirrored);
glTexSubImage1D(GL_TEXTURE_1D, level, cube.x, cube.width, format.dataFormat, format.dataType, mirrored);
break;
case nzImageType_2D:
glTexSubImage1D(GL_TEXTURE_2D, level, cube.x, cube.y, cube.width, cube.height, format->dataFormat, format->dataType, mirrored);
glTexSubImage2D(GL_TEXTURE_2D, level, cube.x, cube.y, cube.width, cube.height, format.dataFormat, format.dataType, mirrored);
break;
case nzImageType_3D:
glTexSubImage1D(GL_TEXTURE_3D, level, cube.x, cube.y, cube.z, cube.width, cube.height, cube.depth, format->dataFormat, format->dataType, mirrored);
glTexSubImage3D(GL_TEXTURE_3D, level, cube.x, cube.y, cube.z, cube.width, cube.height, cube.depth, format.dataFormat, format.dataType, mirrored);
break;
default:
@@ -1284,7 +1373,7 @@ bool NzTexture::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 leve
return true;
}
*/
bool NzTexture::UpdateFace(nzCubemapFace face, const NzImage& image, nzUInt8 level)
{
#if NAZARA_RENDERER_SAFE
@@ -1345,6 +1434,12 @@ bool NzTexture::UpdateFace(nzCubemapFace face, const nzUInt8* pixels, const NzRe
return false;
}
if (m_impl->isTarget)
{
NazaraError("Texture is a target, it cannot be updated");
return false;
}
if (m_impl->type != nzImageType_Cubemap)
{
NazaraError("UpdateFace is designed for cubemaps, use Update instead");
@@ -1433,14 +1528,6 @@ unsigned int NzTexture::GetValidSize(unsigned int size)
bool NzTexture::IsFormatSupported(nzPixelFormat format)
{
#if NAZARA_RENDERER_SAFE
if (!NzPixelFormat::IsValid(format))
{
NazaraError("Invalid pixel format");
return nzPixelFormat_Undefined;
}
#endif
switch (format)
{
// Formats de base
@@ -1468,9 +1555,14 @@ bool NzTexture::IsFormatSupported(nzPixelFormat format)
return supported;
}
default:
return false;
case nzPixelFormat_Undefined:
case nzPixelFormat_Count:
break;
}
NazaraError("Invalid pixel format");
return false;
}
bool NzTexture::IsTypeSupported(nzImageType type)
@@ -1487,3 +1579,16 @@ bool NzTexture::IsTypeSupported(nzImageType type)
return false;
}
}
void NzTexture::SetTarget(bool isTarget)
{
#if NAZARA_RENDERER_SAFE
if (!IsValid())
{
NazaraInternalError("Texture must be valid");
return;
}
#endif
m_impl->isTarget = isTarget;
}

View File

@@ -97,7 +97,7 @@ bool NzVertexBuffer::IsHardware() const
return m_buffer->IsHardware();
}
void* NzVertexBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int length)
void* NzVertexBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int length)
{
#if NAZARA_RENDERER_SAFE
if (offset+length > m_vertexCount)
@@ -107,10 +107,10 @@ void* NzVertexBuffer::Lock(nzBufferLock lock, unsigned int offset, unsigned int
}
#endif
return m_buffer->Lock(lock, m_startVertex+offset, (length) ? length : m_vertexCount-offset);
return m_buffer->Map(access, m_startVertex+offset, (length) ? length : m_vertexCount-offset);
}
bool NzVertexBuffer::Unlock()
bool NzVertexBuffer::Unmap()
{
return m_buffer->Unlock();
return m_buffer->Unmap();
}

View File

@@ -701,21 +701,72 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
return false;
}
if (level >= m_sharedImage->levelCount)
{
NazaraError("Level out of bounds (" + NzString::Number(level) + " >= " + NzString::Number(m_sharedImage->levelCount) + ')');
return false;
}
#endif
unsigned int width = std::max(m_sharedImage->width >> level, 1U);
unsigned int height = std::max(m_sharedImage->height >> level, 1U);
#if NAZARA_UTILITY_SAFE
if (!rect.IsValid())
{
NazaraError("Invalid rectangle");
return false;
}
if (rect.x+rect.width > std::max(m_sharedImage->width >> level, 1U) || rect.y+rect.height > std::max(m_sharedImage->height >> level, 1U))
if (rect.x+rect.width > width || rect.y+rect.height > height)
{
NazaraError("Rectangle dimensions are out of bounds");
return false;
}
if (z >= std::max(m_sharedImage->depth >> level, 1U))
unsigned int depth = std::max(m_sharedImage->depth >> level, 1U);
if (z >= depth)
{
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(m_sharedImage->depth) + ')');
NazaraError("Z value exceeds depth (" + NzString::Number(z) + " >= (" + NzString::Number(depth) + ')');
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(height*(width*z + rect.y) + rect.x) * bpp];
unsigned int srcStride = rect.width * bpp;
unsigned int blockSize = width * bpp;
for (unsigned int i = 0; i < rect.height; ++i)
{
std::memcpy(dstPixels, pixels, blockSize);
pixels += srcStride;
dstPixels += blockSize;
}
return true;
}
bool NzImage::Update(const nzUInt8* pixels, const NzCubeui& cube, nzUInt8 level)
{
///FIXME: Vérifier que ça fonctionne correctement
#if NAZARA_UTILITY_SAFE
if (!IsValid())
{
NazaraError("Image must be valid");
return false;
}
if (m_sharedImage->type == nzImageType_Cubemap)
{
NazaraError("Update is not designed for cubemaps, use UpdateFace instead");
return false;
}
if (!pixels)
{
NazaraError("Invalid pixel source");
return false;
}
@@ -726,17 +777,42 @@ bool NzImage::Update(const nzUInt8* pixels, const NzRectui& rect, unsigned int z
}
#endif
unsigned int width = std::max(m_sharedImage->width >> level, 1U);
unsigned int height = std::max(m_sharedImage->height >> level, 1U);
unsigned int depth = std::max(m_sharedImage->height >> level, 1U);
#if NAZARA_UTILITY_SAFE
if (!cube.IsValid())
{
NazaraError("Invalid cube");
return false;
}
if (cube.x+cube.width > width || cube.y+cube.height > height || cube.z+cube.depth > depth)
{
NazaraError("Cube dimensions are out of bounds");
return false;
}
#endif
EnsureOwnership();
nzUInt8 bpp = NzPixelFormat::GetBPP(m_sharedImage->format);
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(m_sharedImage->height*(m_sharedImage->width*z + rect.y) + rect.x) * bpp];
unsigned int srcStride = rect.width * bpp;
unsigned int blockSize = m_sharedImage->width * bpp;
for (unsigned int i = 0; i < rect.height; ++i)
nzUInt8* dstPixels = &m_sharedImage->pixels[level][(height*(width*cube.z + cube.y) + cube.x) * bpp];
unsigned int srcStride = cube.width * bpp;
unsigned int blockSize = width * bpp;
unsigned int faceSize = width * height * bpp;
for (unsigned int z = 0; z < cube.depth; ++z)
{
std::memcpy(dstPixels, pixels, blockSize);
pixels += srcStride;
dstPixels += blockSize;
nzUInt8* facePixels = dstPixels;
for (unsigned int i = 0; i < cube.height; ++i)
{
std::memcpy(dstPixels, pixels, blockSize);
pixels += srcStride;
facePixels += blockSize;
}
dstPixels += faceSize;
}
return true;

View File

@@ -21,19 +21,19 @@ namespace
{
int Read(void* userdata, char* data, int size)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
return static_cast<int>(stream->Read(data, size));
}
void Skip(void* userdata, unsigned int size)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
stream->Read(nullptr, size);
}
int Eof(void* userdata)
{
NzInputStream* stream = static_cast<NzInputStream*>(userdata);
NzInputStream* stream = reinterpret_cast<NzInputStream*>(userdata);
return stream->GetCursorPos() >= stream->GetSize();
}
@@ -63,7 +63,8 @@ namespace
{
NazaraUnused(parameters);
static nzPixelFormat formats[4] = {
static const nzPixelFormat formats[4] =
{
nzPixelFormat_L8,
nzPixelFormat_LA8,
nzPixelFormat_RGB8,
@@ -134,7 +135,7 @@ namespace
NazaraUnused(parameters);
int width, height, bpp;
return stbi_info_from_memory(static_cast<const stbi_uc*>(data), size, &width, &height, &bpp);
return stbi_info_from_memory(reinterpret_cast<const stbi_uc*>(data), size, &width, &height, &bpp);
}
bool NzLoader_STB_IsStreamLoadingSupported(NzInputStream& stream, const NzImageParams& parameters)

View File

@@ -1317,4 +1317,4 @@ void NzPixelFormat::Uninitialize()
std::memset(s_convertFunctions, 0, nzPixelFormat_Count*nzPixelFormat_Count*sizeof(NzPixelFormat::ConvertFunction));
}
NzPixelFormat::ConvertFunction NzPixelFormat::s_convertFunctions[nzPixelFormat_Count][nzPixelFormat_Count] = {{0}};
NzPixelFormat::ConvertFunction NzPixelFormat::s_convertFunctions[nzPixelFormat_Count][nzPixelFormat_Count] = {{0}}; ///FIXME: Fonctionne correctement ?

View File

@@ -18,7 +18,7 @@ NzVector2i NzEventImpl::GetMousePosition()
NzVector2i NzEventImpl::GetMousePosition(const NzWindow& relativeTo)
{
HWND handle = static_cast<HWND>(relativeTo.GetHandle());
HWND handle = reinterpret_cast<HWND>(relativeTo.GetHandle());
if (handle)
{
POINT pos;
@@ -229,7 +229,7 @@ void NzEventImpl::SetMousePosition(int x, int y)
void NzEventImpl::SetMousePosition(int x, int y, const NzWindow& relativeTo)
{
HWND handle = static_cast<HWND>(relativeTo.GetHandle());
HWND handle = reinterpret_cast<HWND>(relativeTo.GetHandle());
if (handle)
{
POINT pos = {x, y};

View File

@@ -166,7 +166,7 @@ bool NzWindowImpl::Create(NzWindowHandle handle)
return false;
}
m_handle = static_cast<HWND>(handle);
m_handle = reinterpret_cast<HWND>(handle);
m_eventListener = false;
m_ownsWindow = false;
@@ -354,7 +354,7 @@ void NzWindowImpl::ShowMouseCursor(bool show)
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms648045(v=vs.85).aspx
if (show)
m_cursor = static_cast<HCURSOR>(LoadImage(nullptr, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
m_cursor = reinterpret_cast<HCURSOR>(LoadImage(nullptr, MAKEINTRESOURCE(OCR_NORMAL), IMAGE_CURSOR, 0, 0, LR_SHARED));
else
m_cursor = nullptr;