Normalized line ending
Former-commit-id: bd061c48bdc8f0d26159dac3b41017defef5ae1e
This commit is contained in:
@@ -1,359 +1,359 @@
|
||||
// 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/Context.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#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>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <Nazara/Renderer/Linux/ContextImpl.hpp>
|
||||
#else
|
||||
#error Lack of implementation: Context
|
||||
#endif
|
||||
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
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)
|
||||
{
|
||||
NazaraUnused(length);
|
||||
|
||||
NzStringStream ss;
|
||||
ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n";
|
||||
ss << "Sent by context: " << userParam;
|
||||
ss << "\n-Source: ";
|
||||
switch (source)
|
||||
{
|
||||
case GL_DEBUG_SOURCE_API_ARB:
|
||||
ss << "OpenGL";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
|
||||
ss << "Operating system";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
|
||||
ss << "Shader compiler";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
|
||||
ss << "Shader compiler";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_APPLICATION_ARB:
|
||||
ss << "Application";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_OTHER_ARB:
|
||||
ss << "Other";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "-Type: ";
|
||||
switch (type)
|
||||
{
|
||||
case GL_DEBUG_TYPE_ERROR_ARB:
|
||||
ss << "Error";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
|
||||
ss << "Deprecated behavior";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
||||
ss << "Undefined behavior";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_PORTABILITY_ARB:
|
||||
ss << "Portability";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
|
||||
ss << "Performance";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_OTHER_ARB:
|
||||
ss << "Other";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "-Severity: ";
|
||||
switch (severity)
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH_ARB:
|
||||
ss << "High";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
|
||||
ss << "Medium";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_LOW_ARB:
|
||||
ss << "Low";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "Message: " << message << '\n';
|
||||
|
||||
NazaraNotice(ss);
|
||||
}
|
||||
}
|
||||
|
||||
NzContext::NzContext() :
|
||||
m_impl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzContext::~NzContext()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzContext::Create(const NzContextParameters& parameters)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_parameters = parameters;
|
||||
if (m_parameters.shared && !m_parameters.shareContext)
|
||||
m_parameters.shareContext = s_reference;
|
||||
|
||||
m_impl = new NzContextImpl;
|
||||
if (!m_impl->Create(m_parameters))
|
||||
{
|
||||
NazaraError("Failed to create context implementation");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_impl->Activate())
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_parameters.antialiasingLevel > 0)
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
if (NzOpenGL::IsSupported(nzOpenGLExtension_DebugOutput) && m_parameters.debugMode)
|
||||
{
|
||||
glDebugMessageCallback(&DebugCallback, this);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
#endif
|
||||
}
|
||||
|
||||
NotifyCreated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
NotifyDestroy();
|
||||
|
||||
if (currentContext == this)
|
||||
NzContextImpl::Desactivate();
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const NzContextParameters& NzContext::GetParameters() const
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
NazaraError("No context has been created");
|
||||
#endif
|
||||
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
bool NzContext::IsActive() const
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return currentContext == this;
|
||||
}
|
||||
|
||||
bool NzContext::SetActive(bool active)
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Si le contexte est déjà activé/désactivé
|
||||
if ((currentContext == this) == active)
|
||||
return true;
|
||||
|
||||
if (active)
|
||||
{
|
||||
if (!m_impl->Activate())
|
||||
return false;
|
||||
|
||||
currentContext = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!NzContextImpl::Desactivate())
|
||||
return false;
|
||||
|
||||
currentContext = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::SwapBuffers()
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_parameters.doubleBuffered)
|
||||
{
|
||||
NazaraError("Context is not double buffered");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->SwapBuffers();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!threadContext->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to active thread context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NzContext* NzContext::GetCurrent()
|
||||
{
|
||||
return currentContext;
|
||||
}
|
||||
|
||||
const NzContext* NzContext::GetReference()
|
||||
{
|
||||
return s_reference;
|
||||
}
|
||||
|
||||
NzContext* NzContext::GetThreadContext()
|
||||
{
|
||||
EnsureContext();
|
||||
|
||||
return threadContext;
|
||||
}
|
||||
|
||||
bool NzContext::Initialize()
|
||||
{
|
||||
NzContextParameters parameters;
|
||||
// parameters.compatibilityProfile = true;
|
||||
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))
|
||||
{
|
||||
delete s_reference;
|
||||
s_reference = nullptr;
|
||||
|
||||
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::Uninitialize()
|
||||
{
|
||||
for (NzContext* context : contexts)
|
||||
delete context;
|
||||
|
||||
contexts.clear(); // On supprime tous les contextes créés
|
||||
|
||||
delete s_reference;
|
||||
s_reference = nullptr;
|
||||
}
|
||||
|
||||
NzContext* NzContext::s_reference = nullptr;
|
||||
// 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/Context.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#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>
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
#include <Nazara/Renderer/Linux/ContextImpl.hpp>
|
||||
#else
|
||||
#error Lack of implementation: Context
|
||||
#endif
|
||||
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
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)
|
||||
{
|
||||
NazaraUnused(length);
|
||||
|
||||
NzStringStream ss;
|
||||
ss << "OpenGL debug message (ID: 0x" << NzString::Number(id, 16) << "):\n";
|
||||
ss << "Sent by context: " << userParam;
|
||||
ss << "\n-Source: ";
|
||||
switch (source)
|
||||
{
|
||||
case GL_DEBUG_SOURCE_API_ARB:
|
||||
ss << "OpenGL";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB:
|
||||
ss << "Operating system";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB:
|
||||
ss << "Shader compiler";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_THIRD_PARTY_ARB:
|
||||
ss << "Shader compiler";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_APPLICATION_ARB:
|
||||
ss << "Application";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SOURCE_OTHER_ARB:
|
||||
ss << "Other";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "-Type: ";
|
||||
switch (type)
|
||||
{
|
||||
case GL_DEBUG_TYPE_ERROR_ARB:
|
||||
ss << "Error";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB:
|
||||
ss << "Deprecated behavior";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB:
|
||||
ss << "Undefined behavior";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_PORTABILITY_ARB:
|
||||
ss << "Portability";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_PERFORMANCE_ARB:
|
||||
ss << "Performance";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_TYPE_OTHER_ARB:
|
||||
ss << "Other";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "-Severity: ";
|
||||
switch (severity)
|
||||
{
|
||||
case GL_DEBUG_SEVERITY_HIGH_ARB:
|
||||
ss << "High";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_MEDIUM_ARB:
|
||||
ss << "Medium";
|
||||
break;
|
||||
|
||||
case GL_DEBUG_SEVERITY_LOW_ARB:
|
||||
ss << "Low";
|
||||
break;
|
||||
|
||||
default:
|
||||
// Peut être rajouté par une extension
|
||||
ss << "Unknown";
|
||||
break;
|
||||
}
|
||||
ss << '\n';
|
||||
|
||||
ss << "Message: " << message << '\n';
|
||||
|
||||
NazaraNotice(ss);
|
||||
}
|
||||
}
|
||||
|
||||
NzContext::NzContext() :
|
||||
m_impl(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
NzContext::~NzContext()
|
||||
{
|
||||
Destroy();
|
||||
}
|
||||
|
||||
bool NzContext::Create(const NzContextParameters& parameters)
|
||||
{
|
||||
Destroy();
|
||||
|
||||
m_parameters = parameters;
|
||||
if (m_parameters.shared && !m_parameters.shareContext)
|
||||
m_parameters.shareContext = s_reference;
|
||||
|
||||
m_impl = new NzContextImpl;
|
||||
if (!m_impl->Create(m_parameters))
|
||||
{
|
||||
NazaraError("Failed to create context implementation");
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_impl->Activate())
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_parameters.antialiasingLevel > 0)
|
||||
glEnable(GL_MULTISAMPLE);
|
||||
|
||||
if (NzOpenGL::IsSupported(nzOpenGLExtension_DebugOutput) && m_parameters.debugMode)
|
||||
{
|
||||
glDebugMessageCallback(&DebugCallback, this);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
|
||||
#endif
|
||||
}
|
||||
|
||||
NotifyCreated();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::Destroy()
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
NotifyDestroy();
|
||||
|
||||
if (currentContext == this)
|
||||
NzContextImpl::Desactivate();
|
||||
|
||||
m_impl->Destroy();
|
||||
delete m_impl;
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
const NzContextParameters& NzContext::GetParameters() const
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
NazaraError("No context has been created");
|
||||
#endif
|
||||
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
bool NzContext::IsActive() const
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return currentContext == this;
|
||||
}
|
||||
|
||||
bool NzContext::SetActive(bool active)
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Si le contexte est déjà activé/désactivé
|
||||
if ((currentContext == this) == active)
|
||||
return true;
|
||||
|
||||
if (active)
|
||||
{
|
||||
if (!m_impl->Activate())
|
||||
return false;
|
||||
|
||||
currentContext = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!NzContextImpl::Desactivate())
|
||||
return false;
|
||||
|
||||
currentContext = nullptr;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzContext::SwapBuffers()
|
||||
{
|
||||
#ifdef NAZARA_RENDERER_SAFE
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("No context has been created");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_parameters.doubleBuffered)
|
||||
{
|
||||
NazaraError("Context is not double buffered");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
m_impl->SwapBuffers();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!threadContext->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to active thread context");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
NzContext* NzContext::GetCurrent()
|
||||
{
|
||||
return currentContext;
|
||||
}
|
||||
|
||||
const NzContext* NzContext::GetReference()
|
||||
{
|
||||
return s_reference;
|
||||
}
|
||||
|
||||
NzContext* NzContext::GetThreadContext()
|
||||
{
|
||||
EnsureContext();
|
||||
|
||||
return threadContext;
|
||||
}
|
||||
|
||||
bool NzContext::Initialize()
|
||||
{
|
||||
NzContextParameters parameters;
|
||||
// parameters.compatibilityProfile = true;
|
||||
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))
|
||||
{
|
||||
delete s_reference;
|
||||
s_reference = nullptr;
|
||||
|
||||
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::Uninitialize()
|
||||
{
|
||||
for (NzContext* context : contexts)
|
||||
delete context;
|
||||
|
||||
contexts.clear(); // On supprime tous les contextes créés
|
||||
|
||||
delete s_reference;
|
||||
s_reference = nullptr;
|
||||
}
|
||||
|
||||
NzContext* NzContext::s_reference = nullptr;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,81 +1,81 @@
|
||||
// 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
|
||||
|
||||
#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 NzResource;
|
||||
|
||||
class NzGLSLShader : public NzShaderImpl, NzResourceListener
|
||||
{
|
||||
public:
|
||||
NzGLSLShader(NzShader* parent);
|
||||
~NzGLSLShader();
|
||||
|
||||
bool Bind();
|
||||
bool BindTextures();
|
||||
|
||||
bool Compile();
|
||||
|
||||
bool Create();
|
||||
void Destroy();
|
||||
|
||||
NzString GetLog() const;
|
||||
nzShaderLanguage GetLanguage() const;
|
||||
NzString GetSourceCode(nzShaderType type) const;
|
||||
int GetUniformLocation(const NzString& name) const;
|
||||
|
||||
bool IsLoaded(nzShaderType type) const;
|
||||
|
||||
bool Load(nzShaderType type, const NzString& source);
|
||||
bool Lock();
|
||||
|
||||
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;
|
||||
const NzTexture* texture;
|
||||
};
|
||||
|
||||
mutable std::map<NzString, GLint> m_idCache;
|
||||
std::map<GLint, TextureSlot> m_textures;
|
||||
GLuint m_program;
|
||||
GLuint m_shaders[nzShaderType_Max+1];
|
||||
NzShader* m_parent;
|
||||
NzString m_log;
|
||||
};
|
||||
|
||||
#endif // NAZARA_GLSLSHADER_HPPs
|
||||
// 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
|
||||
|
||||
#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 NzResource;
|
||||
|
||||
class NzGLSLShader : public NzShaderImpl, NzResourceListener
|
||||
{
|
||||
public:
|
||||
NzGLSLShader(NzShader* parent);
|
||||
~NzGLSLShader();
|
||||
|
||||
bool Bind();
|
||||
bool BindTextures();
|
||||
|
||||
bool Compile();
|
||||
|
||||
bool Create();
|
||||
void Destroy();
|
||||
|
||||
NzString GetLog() const;
|
||||
nzShaderLanguage GetLanguage() const;
|
||||
NzString GetSourceCode(nzShaderType type) const;
|
||||
int GetUniformLocation(const NzString& name) const;
|
||||
|
||||
bool IsLoaded(nzShaderType type) const;
|
||||
|
||||
bool Load(nzShaderType type, const NzString& source);
|
||||
bool Lock();
|
||||
|
||||
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;
|
||||
const NzTexture* texture;
|
||||
};
|
||||
|
||||
mutable std::map<NzString, GLint> m_idCache;
|
||||
std::map<GLint, TextureSlot> m_textures;
|
||||
GLuint m_program;
|
||||
GLuint m_shaders[nzShaderType_Max+1];
|
||||
NzShader* m_parent;
|
||||
NzString m_log;
|
||||
};
|
||||
|
||||
#endif // NAZARA_GLSLSHADER_HPPs
|
||||
|
||||
@@ -1,218 +1,218 @@
|
||||
// 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/HardwareBuffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
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)
|
||||
{
|
||||
NazaraUnused(size);
|
||||
|
||||
if (access == nzBufferAccess_DiscardAndWrite)
|
||||
{
|
||||
GLint bufSize;
|
||||
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_SIZE, &bufSize);
|
||||
|
||||
GLint bufUsage;
|
||||
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_USAGE, &bufUsage);
|
||||
|
||||
// On discard le buffer
|
||||
glBufferData(NzOpenGL::BufferTargetBinding[type], bufSize, nullptr, bufUsage);
|
||||
}
|
||||
|
||||
void* ptr = glMapBuffer(NzOpenGL::BufferTarget[type], NzOpenGL::BufferLock[access]);
|
||||
if (ptr)
|
||||
return reinterpret_cast<nzUInt8*>(ptr) + offset;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
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);
|
||||
|
||||
LockRoutine mapBuffer = LockBufferFirstRun;
|
||||
|
||||
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
if (glMapBufferRange)
|
||||
mapBuffer = LockBufferRange;
|
||||
else
|
||||
mapBuffer = LockBuffer;
|
||||
|
||||
return mapBuffer(type, access, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
NzHardwareBuffer::NzHardwareBuffer(NzBuffer* parent, nzBufferType type) :
|
||||
m_type(type),
|
||||
m_parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzHardwareBuffer::~NzHardwareBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void NzHardwareBuffer::Bind()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
m_buffer = 0;
|
||||
glGenBuffers(1, &m_buffer);
|
||||
|
||||
GLint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], &previous);
|
||||
|
||||
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
|
||||
if (previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != 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/
|
||||
if (size < 32*1024)
|
||||
{
|
||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||
if (size == m_parent->GetSize())
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
glBufferSubData(NzOpenGL::BufferTarget[m_type], offset, size, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memcpy(ptr, data, size);
|
||||
|
||||
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
|
||||
{
|
||||
// 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(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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::GetPointer()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::IsHardware() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != 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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Unmap()
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
|
||||
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
|
||||
{
|
||||
// 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(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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
// 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/HardwareBuffer.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <stdexcept>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
namespace
|
||||
{
|
||||
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)
|
||||
{
|
||||
NazaraUnused(size);
|
||||
|
||||
if (access == nzBufferAccess_DiscardAndWrite)
|
||||
{
|
||||
GLint bufSize;
|
||||
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_SIZE, &bufSize);
|
||||
|
||||
GLint bufUsage;
|
||||
glGetBufferParameteriv(NzOpenGL::BufferTargetBinding[type], GL_BUFFER_USAGE, &bufUsage);
|
||||
|
||||
// On discard le buffer
|
||||
glBufferData(NzOpenGL::BufferTargetBinding[type], bufSize, nullptr, bufUsage);
|
||||
}
|
||||
|
||||
void* ptr = glMapBuffer(NzOpenGL::BufferTarget[type], NzOpenGL::BufferLock[access]);
|
||||
if (ptr)
|
||||
return reinterpret_cast<nzUInt8*>(ptr) + offset;
|
||||
else
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nzUInt8* LockBufferRange(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
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);
|
||||
|
||||
LockRoutine mapBuffer = LockBufferFirstRun;
|
||||
|
||||
nzUInt8* LockBufferFirstRun(nzBufferType type, nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
if (glMapBufferRange)
|
||||
mapBuffer = LockBufferRange;
|
||||
else
|
||||
mapBuffer = LockBuffer;
|
||||
|
||||
return mapBuffer(type, access, offset, size);
|
||||
}
|
||||
}
|
||||
|
||||
NzHardwareBuffer::NzHardwareBuffer(NzBuffer* parent, nzBufferType type) :
|
||||
m_type(type),
|
||||
m_parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
NzHardwareBuffer::~NzHardwareBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
void NzHardwareBuffer::Bind()
|
||||
{
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (NzContext::GetCurrent() == nullptr)
|
||||
{
|
||||
NazaraError("No active context");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Create(unsigned int size, nzBufferUsage usage)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
m_buffer = 0;
|
||||
glGenBuffers(1, &m_buffer);
|
||||
|
||||
GLint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], &previous);
|
||||
|
||||
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
|
||||
if (previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != 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/
|
||||
if (size < 32*1024)
|
||||
{
|
||||
// http://www.opengl.org/wiki/Vertex_Specification_Best_Practices
|
||||
if (size == m_parent->GetSize())
|
||||
glBufferData(NzOpenGL::BufferTarget[m_type], m_parent->GetSize(), nullptr, NzOpenGL::BufferUsage[m_parent->GetUsage()]); // Discard
|
||||
|
||||
glBufferSubData(NzOpenGL::BufferTarget[m_type], offset, size, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
nzUInt8* ptr = mapBuffer(m_type, (size == m_parent->GetSize()) ? nzBufferAccess_DiscardAndWrite : nzBufferAccess_WriteOnly, offset, size);
|
||||
if (!ptr)
|
||||
{
|
||||
NazaraError("Failed to map buffer");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::memcpy(ptr, data, size);
|
||||
|
||||
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
|
||||
{
|
||||
// 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(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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::GetPointer()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::IsHardware() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* NzHardwareBuffer::Map(nzBufferAccess access, unsigned int offset, unsigned int size)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
// Pour ne pas perturber le rendu, on interfère pas avec le binding déjà présent
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != 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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
bool NzHardwareBuffer::Unmap()
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint previous;
|
||||
glGetIntegerv(NzOpenGL::BufferTargetBinding[m_type], reinterpret_cast<GLint*>(&previous));
|
||||
|
||||
if (previous != m_buffer)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], m_buffer);
|
||||
|
||||
if (glUnmapBuffer(NzOpenGL::BufferTarget[m_type]) != GL_TRUE)
|
||||
{
|
||||
// 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(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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
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)
|
||||
if (previous != m_buffer && previous != 0)
|
||||
glBindBuffer(NzOpenGL::BufferTarget[m_type], previous);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,98 +1,98 @@
|
||||
// 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/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>
|
||||
|
||||
NzOcclusionQuery::NzOcclusionQuery() :
|
||||
m_id(0)
|
||||
{
|
||||
if (IsSupported())
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
glGenQueries(1, reinterpret_cast<GLuint*>(&m_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Occlusion queries not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_id)
|
||||
{
|
||||
NazaraError("Failed to create occlusion query");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzOcclusionQuery::~NzOcclusionQuery()
|
||||
{
|
||||
if (m_id)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint query = static_cast<GLuint>(m_id);
|
||||
glDeleteQueries(1, &query);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NzOcclusionQuery::IsResultAvailable() const
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLint available;
|
||||
glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available);
|
||||
|
||||
return available == GL_TRUE;
|
||||
}
|
||||
|
||||
bool NzOcclusionQuery::IsSupported()
|
||||
{
|
||||
return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery);
|
||||
}
|
||||
// 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/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>
|
||||
|
||||
NzOcclusionQuery::NzOcclusionQuery() :
|
||||
m_id(0)
|
||||
{
|
||||
if (IsSupported())
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
glGenQueries(1, reinterpret_cast<GLuint*>(&m_id));
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Occlusion queries not supported");
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_id)
|
||||
{
|
||||
NazaraError("Failed to create occlusion query");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzOcclusionQuery::~NzOcclusionQuery()
|
||||
{
|
||||
if (m_id)
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLuint query = static_cast<GLuint>(m_id);
|
||||
glDeleteQueries(1, &query);
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool NzOcclusionQuery::IsResultAvailable() const
|
||||
{
|
||||
NzContext::EnsureContext();
|
||||
|
||||
GLint available;
|
||||
glGetQueryObjectiv(m_id, GL_QUERY_RESULT_AVAILABLE, &available);
|
||||
|
||||
return available == GL_TRUE;
|
||||
}
|
||||
|
||||
bool NzOcclusionQuery::IsSupported()
|
||||
{
|
||||
return NzRenderer::HasCapability(nzRendererCap_OcclusionQuery);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,276 +1,276 @@
|
||||
// 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(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||
{
|
||||
Create(mode, title, style, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||
{
|
||||
Create(handle, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::~NzRenderWindow()
|
||||
{
|
||||
// Nécessaire si NzWindow::Destroy est appelé par son destructeur
|
||||
OnWindowDestroy();
|
||||
}
|
||||
|
||||
bool NzRenderWindow::CopyToImage(NzImage* image)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
NazaraError("Image must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1))
|
||||
{
|
||||
NazaraError("Failed to create image");
|
||||
return false;
|
||||
}
|
||||
|
||||
nzUInt8* pixels = image->GetPixels();
|
||||
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
image->FlipVertically();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::CopyToTexture(NzTexture* texture)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
NazaraError("Texture must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1, true))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y);
|
||||
|
||||
texture->Unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return NzWindow::Create(mode, title, style);
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return NzWindow::Create(handle);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void NzRenderWindow::EnableVerticalSync(bool enabled)
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (wglSwapInterval)
|
||||
wglSwapInterval(enabled ? 1 : 0);
|
||||
else
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (glXSwapInterval)
|
||||
glXSwapInterval(enabled ? 1 : 0);
|
||||
else
|
||||
#else
|
||||
#error Vertical Sync is not supported on this platform
|
||||
#endif
|
||||
NazaraError("Vertical Sync is not supported on this platform");
|
||||
}
|
||||
else
|
||||
NazaraError("No context");
|
||||
}
|
||||
|
||||
unsigned int NzRenderWindow::GetHeight() const
|
||||
{
|
||||
return NzWindow::GetHeight();
|
||||
}
|
||||
|
||||
NzRenderTargetParameters NzRenderWindow::GetParameters() const
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
const NzContextParameters& parameters = m_context->GetParameters();
|
||||
return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Window not created/context not initialized");
|
||||
return NzRenderTargetParameters();
|
||||
}
|
||||
}
|
||||
|
||||
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::Activate()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzRenderWindow::OnWindowCreated()
|
||||
{
|
||||
m_parameters.doubleBuffered = true;
|
||||
m_parameters.window = GetHandle();
|
||||
|
||||
m_context = new NzContext;
|
||||
if (!m_context->Create(m_parameters))
|
||||
{
|
||||
NazaraError("Failed not create context");
|
||||
delete m_context;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EnableVerticalSync(false);
|
||||
|
||||
if (!SetActive(true)) // Les fenêtres s'activent à la création
|
||||
NazaraWarning("Failed to activate window");
|
||||
|
||||
m_clock.Restart();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void NzRenderWindow::OnWindowDestroy()
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
delete m_context;
|
||||
m_context = nullptr;
|
||||
}
|
||||
}
|
||||
// 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(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||
{
|
||||
Create(mode, title, style, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::NzRenderWindow(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||
{
|
||||
Create(handle, parameters);
|
||||
|
||||
#ifdef NAZARA_DEBUG
|
||||
if (!m_impl)
|
||||
{
|
||||
NazaraError("Failed to create render window");
|
||||
throw std::runtime_error("Constructor failed");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NzRenderWindow::~NzRenderWindow()
|
||||
{
|
||||
// Nécessaire si NzWindow::Destroy est appelé par son destructeur
|
||||
OnWindowDestroy();
|
||||
}
|
||||
|
||||
bool NzRenderWindow::CopyToImage(NzImage* image)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!image)
|
||||
{
|
||||
NazaraError("Image must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1))
|
||||
{
|
||||
NazaraError("Failed to create image");
|
||||
return false;
|
||||
}
|
||||
|
||||
nzUInt8* pixels = image->GetPixels();
|
||||
glReadPixels(0, 0, size.x, size.y, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
|
||||
|
||||
image->FlipVertically();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::CopyToTexture(NzTexture* texture)
|
||||
{
|
||||
#if NAZARA_RENDERER_SAFE
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Window has not been created");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!texture)
|
||||
{
|
||||
NazaraError("Texture must be valid");
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return false;
|
||||
}
|
||||
|
||||
NzVector2ui size = GetSize();
|
||||
|
||||
if (!texture->Create(nzImageType_2D, nzPixelFormat_RGBA8, size.x, size.y, 1, 1, true))
|
||||
{
|
||||
NazaraError("Failed to create texture");
|
||||
return false;
|
||||
}
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, size.x, size.y);
|
||||
|
||||
texture->Unlock();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Create(NzVideoMode mode, const NzString& title, nzUInt32 style, const NzContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return NzWindow::Create(mode, title, style);
|
||||
}
|
||||
|
||||
bool NzRenderWindow::Create(NzWindowHandle handle, const NzContextParameters& parameters)
|
||||
{
|
||||
m_parameters = parameters;
|
||||
return NzWindow::Create(handle);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
void NzRenderWindow::EnableVerticalSync(bool enabled)
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
#if defined(NAZARA_PLATFORM_WINDOWS)
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (wglSwapInterval)
|
||||
wglSwapInterval(enabled ? 1 : 0);
|
||||
else
|
||||
#elif defined(NAZARA_PLATFORM_LINUX)
|
||||
if (!m_context->SetActive(true))
|
||||
{
|
||||
NazaraError("Failed to activate context");
|
||||
return;
|
||||
}
|
||||
|
||||
if (glXSwapInterval)
|
||||
glXSwapInterval(enabled ? 1 : 0);
|
||||
else
|
||||
#else
|
||||
#error Vertical Sync is not supported on this platform
|
||||
#endif
|
||||
NazaraError("Vertical Sync is not supported on this platform");
|
||||
}
|
||||
else
|
||||
NazaraError("No context");
|
||||
}
|
||||
|
||||
unsigned int NzRenderWindow::GetHeight() const
|
||||
{
|
||||
return NzWindow::GetHeight();
|
||||
}
|
||||
|
||||
NzRenderTargetParameters NzRenderWindow::GetParameters() const
|
||||
{
|
||||
if (m_context)
|
||||
{
|
||||
const NzContextParameters& parameters = m_context->GetParameters();
|
||||
return NzRenderTargetParameters(parameters.antialiasingLevel, parameters.depthBits, parameters.stencilBits);
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraError("Window not created/context not initialized");
|
||||
return NzRenderTargetParameters();
|
||||
}
|
||||
}
|
||||
|
||||
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::Activate()
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
bool NzRenderWindow::OnWindowCreated()
|
||||
{
|
||||
m_parameters.doubleBuffered = true;
|
||||
m_parameters.window = GetHandle();
|
||||
|
||||
m_context = new NzContext;
|
||||
if (!m_context->Create(m_parameters))
|
||||
{
|
||||
NazaraError("Failed not create context");
|
||||
delete m_context;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
EnableVerticalSync(false);
|
||||
|
||||
if (!SetActive(true)) // Les fenêtres s'activent à la création
|
||||
NazaraWarning("Failed to activate window");
|
||||
|
||||
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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,234 +1,234 @@
|
||||
// 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
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/LockGuard.hpp>
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
NzContextImpl::NzContextImpl()
|
||||
{
|
||||
}
|
||||
|
||||
bool NzContextImpl::Activate()
|
||||
{
|
||||
return wglMakeCurrent(m_deviceContext, m_context);
|
||||
}
|
||||
|
||||
bool NzContextImpl::Create(NzContextParameters& parameters)
|
||||
{
|
||||
if (parameters.window)
|
||||
{
|
||||
m_window = static_cast<HWND>(parameters.window);
|
||||
m_ownsWindow = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_window = CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
|
||||
if (!m_window)
|
||||
{
|
||||
NazaraError("Failed to create window");
|
||||
return false;
|
||||
}
|
||||
|
||||
ShowWindow(m_window, SW_HIDE);
|
||||
m_ownsWindow = true;
|
||||
}
|
||||
|
||||
m_deviceContext = GetDC(m_window);
|
||||
if (!m_deviceContext)
|
||||
{
|
||||
NazaraError("Failed to get device context");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
int pixelFormat = 0;
|
||||
if (parameters.antialiasingLevel > 0)
|
||||
{
|
||||
if (wglChoosePixelFormat)
|
||||
{
|
||||
bool valid;
|
||||
UINT numFormats;
|
||||
|
||||
int attributes[] = {
|
||||
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
||||
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
||||
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
||||
WGL_COLOR_BITS_ARB, (parameters.bitsPerPixel == 32) ? 24 : parameters.bitsPerPixel,
|
||||
WGL_ALPHA_BITS_ARB, (parameters.bitsPerPixel == 32) ? 8 : 0,
|
||||
WGL_DEPTH_BITS_ARB, parameters.depthBits,
|
||||
WGL_STENCIL_BITS_ARB, parameters.stencilBits,
|
||||
WGL_DOUBLE_BUFFER_ARB, (parameters.doubleBuffered) ? GL_TRUE : GL_FALSE,
|
||||
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
|
||||
WGL_SAMPLES_ARB, parameters.antialiasingLevel,
|
||||
0, 0
|
||||
};
|
||||
|
||||
do
|
||||
{
|
||||
valid = wglChoosePixelFormat(m_deviceContext, attributes, nullptr, 1, &pixelFormat, &numFormats);
|
||||
}
|
||||
while ((!valid || numFormats == 0) && --attributes[19] > 0);
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
NazaraWarning("Could not find a format matching requirements, disabling antialiasing...");
|
||||
pixelFormat = 0;
|
||||
}
|
||||
|
||||
parameters.antialiasingLevel = attributes[19];
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraWarning("Antialiasing is not supported");
|
||||
parameters.antialiasingLevel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PIXELFORMATDESCRIPTOR descriptor;
|
||||
ZeroMemory(&descriptor, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
descriptor.nVersion = 1;
|
||||
|
||||
if (pixelFormat == 0)
|
||||
{
|
||||
descriptor.cColorBits = parameters.bitsPerPixel;
|
||||
descriptor.cDepthBits = parameters.depthBits;
|
||||
descriptor.cStencilBits = parameters.stencilBits;
|
||||
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
||||
descriptor.iPixelType = PFD_TYPE_RGBA;
|
||||
|
||||
if (parameters.bitsPerPixel == 32)
|
||||
descriptor.cAlphaBits = 8;
|
||||
|
||||
if (parameters.doubleBuffered)
|
||||
descriptor.dwFlags |= PFD_DOUBLEBUFFER;
|
||||
|
||||
pixelFormat = ChoosePixelFormat(m_deviceContext, &descriptor);
|
||||
if (pixelFormat == 0)
|
||||
{
|
||||
NazaraError("Failed to choose pixel format");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor))
|
||||
{
|
||||
NazaraError("Failed to set pixel format");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
parameters.depthBits = descriptor.cDepthBits;
|
||||
parameters.stencilBits = descriptor.cDepthBits;
|
||||
}
|
||||
else
|
||||
NazaraWarning("Failed to get context's parameters");
|
||||
|
||||
HGLRC shareContext = (parameters.shared) ? static_cast<NzContextImpl*>(parameters.shareContext->m_impl)->m_context : nullptr;
|
||||
|
||||
m_context = nullptr;
|
||||
if (wglCreateContextAttribs)
|
||||
{
|
||||
int attributes[4*2+1];
|
||||
int* attrib = attributes;
|
||||
|
||||
*attrib++ = WGL_CONTEXT_MAJOR_VERSION_ARB;
|
||||
*attrib++ = parameters.majorVersion;
|
||||
|
||||
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
|
||||
*attrib++ = parameters.minorVersion;
|
||||
|
||||
if (parameters.majorVersion >= 3)
|
||||
{
|
||||
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
|
||||
*attrib++ = (parameters.compatibilityProfile) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
}
|
||||
|
||||
if (parameters.debugMode)
|
||||
{
|
||||
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
|
||||
*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;
|
||||
|
||||
m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes);
|
||||
}
|
||||
|
||||
if (!m_context)
|
||||
{
|
||||
m_context = wglCreateContext(m_deviceContext);
|
||||
|
||||
if (shareContext)
|
||||
{
|
||||
// wglShareLists n'est pas thread-safe (source: SFML)
|
||||
static NzMutex mutex;
|
||||
NzLockGuard lock(mutex);
|
||||
|
||||
if (!wglShareLists(shareContext, m_context))
|
||||
NazaraWarning("Failed to share the context: " + NzGetLastSystemError());
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Failed to create context");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
::SwapBuffers(m_deviceContext);
|
||||
}
|
||||
|
||||
bool NzContextImpl::Desactivate()
|
||||
{
|
||||
return wglMakeCurrent(nullptr, nullptr);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
||||
#include <Nazara/Renderer/OpenGL.hpp>
|
||||
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
|
||||
#include <Nazara/Core/Error.hpp>
|
||||
#include <Nazara/Core/LockGuard.hpp>
|
||||
#include <Nazara/Core/Mutex.hpp>
|
||||
#include <Nazara/Renderer/Context.hpp>
|
||||
#include <cstring>
|
||||
#include <Nazara/Renderer/Debug.hpp>
|
||||
|
||||
NzContextImpl::NzContextImpl()
|
||||
{
|
||||
}
|
||||
|
||||
bool NzContextImpl::Activate()
|
||||
{
|
||||
return wglMakeCurrent(m_deviceContext, m_context);
|
||||
}
|
||||
|
||||
bool NzContextImpl::Create(NzContextParameters& parameters)
|
||||
{
|
||||
if (parameters.window)
|
||||
{
|
||||
m_window = static_cast<HWND>(parameters.window);
|
||||
m_ownsWindow = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_window = CreateWindowA("STATIC", nullptr, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, nullptr, nullptr, GetModuleHandle(nullptr), nullptr);
|
||||
if (!m_window)
|
||||
{
|
||||
NazaraError("Failed to create window");
|
||||
return false;
|
||||
}
|
||||
|
||||
ShowWindow(m_window, SW_HIDE);
|
||||
m_ownsWindow = true;
|
||||
}
|
||||
|
||||
m_deviceContext = GetDC(m_window);
|
||||
if (!m_deviceContext)
|
||||
{
|
||||
NazaraError("Failed to get device context");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
int pixelFormat = 0;
|
||||
if (parameters.antialiasingLevel > 0)
|
||||
{
|
||||
if (wglChoosePixelFormat)
|
||||
{
|
||||
bool valid;
|
||||
UINT numFormats;
|
||||
|
||||
int attributes[] = {
|
||||
WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
|
||||
WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
|
||||
WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB,
|
||||
WGL_COLOR_BITS_ARB, (parameters.bitsPerPixel == 32) ? 24 : parameters.bitsPerPixel,
|
||||
WGL_ALPHA_BITS_ARB, (parameters.bitsPerPixel == 32) ? 8 : 0,
|
||||
WGL_DEPTH_BITS_ARB, parameters.depthBits,
|
||||
WGL_STENCIL_BITS_ARB, parameters.stencilBits,
|
||||
WGL_DOUBLE_BUFFER_ARB, (parameters.doubleBuffered) ? GL_TRUE : GL_FALSE,
|
||||
WGL_SAMPLE_BUFFERS_ARB, GL_TRUE,
|
||||
WGL_SAMPLES_ARB, parameters.antialiasingLevel,
|
||||
0, 0
|
||||
};
|
||||
|
||||
do
|
||||
{
|
||||
valid = wglChoosePixelFormat(m_deviceContext, attributes, nullptr, 1, &pixelFormat, &numFormats);
|
||||
}
|
||||
while ((!valid || numFormats == 0) && --attributes[19] > 0);
|
||||
|
||||
if (!valid)
|
||||
{
|
||||
NazaraWarning("Could not find a format matching requirements, disabling antialiasing...");
|
||||
pixelFormat = 0;
|
||||
}
|
||||
|
||||
parameters.antialiasingLevel = attributes[19];
|
||||
}
|
||||
else
|
||||
{
|
||||
NazaraWarning("Antialiasing is not supported");
|
||||
parameters.antialiasingLevel = 0;
|
||||
}
|
||||
}
|
||||
|
||||
PIXELFORMATDESCRIPTOR descriptor;
|
||||
ZeroMemory(&descriptor, sizeof(PIXELFORMATDESCRIPTOR));
|
||||
descriptor.nSize = sizeof(PIXELFORMATDESCRIPTOR);
|
||||
descriptor.nVersion = 1;
|
||||
|
||||
if (pixelFormat == 0)
|
||||
{
|
||||
descriptor.cColorBits = parameters.bitsPerPixel;
|
||||
descriptor.cDepthBits = parameters.depthBits;
|
||||
descriptor.cStencilBits = parameters.stencilBits;
|
||||
descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
|
||||
descriptor.iPixelType = PFD_TYPE_RGBA;
|
||||
|
||||
if (parameters.bitsPerPixel == 32)
|
||||
descriptor.cAlphaBits = 8;
|
||||
|
||||
if (parameters.doubleBuffered)
|
||||
descriptor.dwFlags |= PFD_DOUBLEBUFFER;
|
||||
|
||||
pixelFormat = ChoosePixelFormat(m_deviceContext, &descriptor);
|
||||
if (pixelFormat == 0)
|
||||
{
|
||||
NazaraError("Failed to choose pixel format");
|
||||
Destroy();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor))
|
||||
{
|
||||
NazaraError("Failed to set pixel format");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
// 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;
|
||||
parameters.depthBits = descriptor.cDepthBits;
|
||||
parameters.stencilBits = descriptor.cDepthBits;
|
||||
}
|
||||
else
|
||||
NazaraWarning("Failed to get context's parameters");
|
||||
|
||||
HGLRC shareContext = (parameters.shared) ? static_cast<NzContextImpl*>(parameters.shareContext->m_impl)->m_context : nullptr;
|
||||
|
||||
m_context = nullptr;
|
||||
if (wglCreateContextAttribs)
|
||||
{
|
||||
int attributes[4*2+1];
|
||||
int* attrib = attributes;
|
||||
|
||||
*attrib++ = WGL_CONTEXT_MAJOR_VERSION_ARB;
|
||||
*attrib++ = parameters.majorVersion;
|
||||
|
||||
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
|
||||
*attrib++ = parameters.minorVersion;
|
||||
|
||||
if (parameters.majorVersion >= 3)
|
||||
{
|
||||
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
|
||||
*attrib++ = (parameters.compatibilityProfile) ? WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
|
||||
}
|
||||
|
||||
if (parameters.debugMode)
|
||||
{
|
||||
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
|
||||
*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;
|
||||
|
||||
m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes);
|
||||
}
|
||||
|
||||
if (!m_context)
|
||||
{
|
||||
m_context = wglCreateContext(m_deviceContext);
|
||||
|
||||
if (shareContext)
|
||||
{
|
||||
// wglShareLists n'est pas thread-safe (source: SFML)
|
||||
static NzMutex mutex;
|
||||
NzLockGuard lock(mutex);
|
||||
|
||||
if (!wglShareLists(shareContext, m_context))
|
||||
NazaraWarning("Failed to share the context: " + NzGetLastSystemError());
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_context)
|
||||
{
|
||||
NazaraError("Failed to create context");
|
||||
Destroy();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
::SwapBuffers(m_deviceContext);
|
||||
}
|
||||
|
||||
bool NzContextImpl::Desactivate()
|
||||
{
|
||||
return wglMakeCurrent(nullptr, nullptr);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user