Added support for OpenGL debug mode

When NzContextParameters.debugMode is true, Nazara will receive OpenGL's
debug message and send them to Nazara's log
NzString::Pointer now have the "0x" prefix
Added support for ARB_texture_storage extension
Nazara now try to load core texture 3D before trying to load
EXT_texture3D
Added NazaraNotice macro, writing raw text into Nazara's log
Added NzContext::Destroy (called in Create)
This commit is contained in:
Lynix 2012-05-31 23:33:47 +02:00
parent f4b194f6fe
commit dd4cb97a37
11 changed files with 317 additions and 67 deletions

View File

@ -16,6 +16,7 @@
#include <Nazara/Core/ThreadSafety.hpp> #include <Nazara/Core/ThreadSafety.hpp>
#define NazaraLog NzLog::Instance() #define NazaraLog NzLog::Instance()
#define NazaraNotice(txt) NazaraLog->Write(txt)
class NzFile; class NzFile;

View File

@ -38,6 +38,9 @@
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution) // Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0 #define NAZARA_RENDERER_MEMORYLEAKTRACKER 0
// Active le paramère debug des paramètres des contextes par défaut (Perte de performances mais capable de recevoir des messages d'OpenGL)
#define NAZARA_RENDERER_OPENGL_DEBUG 0
// Active les tests de sécurité basés sur le code (Conseillé pour le développement) // Active les tests de sécurité basés sur le code (Conseillé pour le développement)
#define NAZARA_RENDERER_SAFE 1 #define NAZARA_RENDERER_SAFE 1

View File

@ -24,6 +24,7 @@ class NAZARA_API NzContext
~NzContext(); ~NzContext();
bool Create(const NzContextParameters& parameters = NzContextParameters()); bool Create(const NzContextParameters& parameters = NzContextParameters());
void Destroy();
const NzContextParameters& GetParameters() const; const NzContextParameters& GetParameters() const;
bool IsActive() const; bool IsActive() const;
bool SetActive(bool active); bool SetActive(bool active);

View File

@ -25,6 +25,7 @@ struct NAZARA_API NzContextParameters
shareContext(defaultShareContext), shareContext(defaultShareContext),
window(defaultWindow), window(defaultWindow),
compatibilityProfile(defaultCompatibilityProfile), compatibilityProfile(defaultCompatibilityProfile),
debugMode(defaultDebugMode),
doubleBuffered(defaultDoubleBuffered), doubleBuffered(defaultDoubleBuffered),
shared(defaultShared) shared(defaultShared)
{ {
@ -39,6 +40,7 @@ struct NAZARA_API NzContextParameters
const NzContext* shareContext; const NzContext* shareContext;
NzWindowHandle window; NzWindowHandle window;
bool compatibilityProfile; bool compatibilityProfile;
bool debugMode;
bool doubleBuffered; bool doubleBuffered;
bool shared; bool shared;
@ -47,6 +49,7 @@ struct NAZARA_API NzContextParameters
static const NzContext* defaultShareContext; static const NzContext* defaultShareContext;
static NzWindowHandle defaultWindow; static NzWindowHandle defaultWindow;
static bool defaultCompatibilityProfile; static bool defaultCompatibilityProfile;
static bool defaultDebugMode;
static bool defaultDoubleBuffered; static bool defaultDoubleBuffered;
static bool defaultShared; static bool defaultShared;
}; };

View File

@ -34,9 +34,11 @@ class NAZARA_API NzOpenGL
enum Extension enum Extension
{ {
AnisotropicFilter, AnisotropicFilter,
DebugOutput,
FP64, FP64,
FrameBufferObject, FrameBufferObject,
Texture3D, Texture3D,
TextureStorage,
VertexArrayObject, VertexArrayObject,
Count Count
@ -71,6 +73,9 @@ NAZARA_API extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
NAZARA_API extern PFNGLCOLORMASKPROC glColorMask; NAZARA_API extern PFNGLCOLORMASKPROC glColorMask;
NAZARA_API extern PFNGLCULLFACEPROC glCullFace; NAZARA_API extern PFNGLCULLFACEPROC glCullFace;
NAZARA_API extern PFNGLCOMPILESHADERPROC glCompileShader; NAZARA_API extern PFNGLCOMPILESHADERPROC glCompileShader;
NAZARA_API extern PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControl;
NAZARA_API extern PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsert;
NAZARA_API extern PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallback;
NAZARA_API extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; NAZARA_API extern PFNGLDELETEBUFFERSPROC glDeleteBuffers;
NAZARA_API extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; NAZARA_API extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
NAZARA_API extern PFNGLDELETEPROGRAMPROC glDeleteProgram; NAZARA_API extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
@ -101,6 +106,7 @@ NAZARA_API extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
NAZARA_API extern PFNGLGENTEXTURESPROC glGenTextures; NAZARA_API extern PFNGLGENTEXTURESPROC glGenTextures;
NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv; NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
NAZARA_API extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLog;
NAZARA_API extern PFNGLGETERRORPROC glGetError; NAZARA_API extern PFNGLGETERRORPROC glGetError;
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv; NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv; NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
@ -126,12 +132,17 @@ NAZARA_API extern PFNGLSCISSORPROC glScissor;
NAZARA_API extern PFNGLSHADERSOURCEPROC glShaderSource; NAZARA_API extern PFNGLSHADERSOURCEPROC glShaderSource;
NAZARA_API extern PFNGLSTENCILFUNCPROC glStencilFunc; NAZARA_API extern PFNGLSTENCILFUNCPROC glStencilFunc;
NAZARA_API extern PFNGLSTENCILOPPROC glStencilOp; NAZARA_API extern PFNGLSTENCILOPPROC glStencilOp;
NAZARA_API extern PFNGLTEXIMAGE1DPROC glTexImage1D;
NAZARA_API extern PFNGLTEXIMAGE2DPROC glTexImage2D; NAZARA_API extern PFNGLTEXIMAGE2DPROC glTexImage2D;
NAZARA_API extern PFNGLTEXIMAGE3DEXTPROC glTexImage3D; NAZARA_API extern PFNGLTEXIMAGE3DPROC glTexImage3D;
NAZARA_API extern PFNGLTEXPARAMETERFPROC glTexParameterf; NAZARA_API extern PFNGLTEXPARAMETERFPROC glTexParameterf;
NAZARA_API extern PFNGLTEXPARAMETERIPROC glTexParameteri; NAZARA_API extern PFNGLTEXPARAMETERIPROC glTexParameteri;
NAZARA_API extern PFNGLTEXSTORAGE1DPROC glTexStorage1D;
NAZARA_API extern PFNGLTEXSTORAGE2DPROC glTexStorage2D;
NAZARA_API extern PFNGLTEXSTORAGE3DPROC glTexStorage3D;
NAZARA_API extern PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D;
NAZARA_API extern PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D; NAZARA_API extern PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D;
NAZARA_API extern PFNGLTEXSUBIMAGE3DEXTPROC glTexSubImage3D; NAZARA_API extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D;
NAZARA_API extern PFNGLUNIFORM1DPROC glUniform1d; NAZARA_API extern PFNGLUNIFORM1DPROC glUniform1d;
NAZARA_API extern PFNGLUNIFORM1FPROC glUniform1f; NAZARA_API extern PFNGLUNIFORM1FPROC glUniform1f;
NAZARA_API extern PFNGLUNIFORM1IPROC glUniform1i; NAZARA_API extern PFNGLUNIFORM1IPROC glUniform1i;

View File

@ -4735,9 +4735,9 @@ NzString NzString::Number(unsigned long long number, nzUInt8 radix)
NzString NzString::Pointer(const void* ptr) NzString NzString::Pointer(const void* ptr)
{ {
unsigned int size = sizeof(ptr)*2; unsigned int size = sizeof(ptr)*2+2;
char* str = new char[size+1]; char* str = new char[size+1];
std::sprintf(str, "%p", ptr); std::sprintf(str, "0x%p", ptr);
return NzString(new SharedString(1, size, size, str)); return NzString(new SharedString(1, size, size, str));
} }

View File

@ -5,6 +5,8 @@
#include <Nazara/Renderer/OpenGL.hpp> #include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/Context.hpp> #include <Nazara/Renderer/Context.hpp>
#include <Nazara/Core/Error.hpp> #include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Core/StringStream.hpp>
#include <Nazara/Renderer/Config.hpp> #include <Nazara/Renderer/Config.hpp>
#if defined(NAZARA_PLATFORM_WINDOWS) #if defined(NAZARA_PLATFORM_WINDOWS)
@ -22,6 +24,108 @@ namespace
///TODO: Thread-local ///TODO: Thread-local
NzContext* currentContext = nullptr; NzContext* currentContext = nullptr;
NzContext* threadContext = nullptr; NzContext* threadContext = nullptr;
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 << "-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;
ss << "\n\nSent by context: " << userParam;
NazaraNotice(ss);
}
} }
NzContext::NzContext() : NzContext::NzContext() :
@ -31,18 +135,13 @@ m_impl(nullptr)
NzContext::~NzContext() NzContext::~NzContext()
{ {
if (m_impl) Destroy();
{
if (currentContext == this)
NzContextImpl::Desactivate();
m_impl->Destroy();
delete m_impl;
}
} }
bool NzContext::Create(const NzContextParameters& parameters) bool NzContext::Create(const NzContextParameters& parameters)
{ {
Destroy();
m_parameters = parameters; m_parameters = parameters;
if (m_parameters.shared && !m_parameters.shareContext) if (m_parameters.shared && !m_parameters.shareContext)
m_parameters.shareContext = s_reference; m_parameters.shareContext = s_reference;
@ -71,9 +170,30 @@ bool NzContext::Create(const NzContextParameters& parameters)
if (m_parameters.antialiasingLevel > 0) if (m_parameters.antialiasingLevel > 0)
glEnable(GL_MULTISAMPLE); glEnable(GL_MULTISAMPLE);
if (NzOpenGL::IsSupported(NzOpenGL::DebugOutput) && m_parameters.debugMode)
{
glDebugMessageCallback(&DebugCallback, this);
#ifdef NAZARA_DEBUG
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB);
#endif
}
return true; return true;
} }
void NzContext::Destroy()
{
if (m_impl)
{
if (currentContext == this)
NzContextImpl::Desactivate();
m_impl->Destroy();
delete m_impl;
}
}
const NzContextParameters& NzContext::GetParameters() const const NzContextParameters& NzContext::GetParameters() const
{ {
#ifdef NAZARA_RENDERER_SAFE #ifdef NAZARA_RENDERER_SAFE

View File

@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp // For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/ContextParameters.hpp> #include <Nazara/Renderer/ContextParameters.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Debug.hpp> #include <Nazara/Renderer/Debug.hpp>
nzUInt8 NzContextParameters::defaultMajorVersion; // Initialisé par NzOpenGL nzUInt8 NzContextParameters::defaultMajorVersion; // Initialisé par NzOpenGL
@ -10,5 +11,10 @@ nzUInt8 NzContextParameters::defaultMinorVersion; // Initialis
const NzContext* NzContextParameters::defaultShareContext = nullptr; const NzContext* NzContextParameters::defaultShareContext = nullptr;
NzWindowHandle NzContextParameters::defaultWindow = 0; NzWindowHandle NzContextParameters::defaultWindow = 0;
bool NzContextParameters::defaultCompatibilityProfile = false; bool NzContextParameters::defaultCompatibilityProfile = false;
#if NAZARA_RENDERER_OPENGL_DEBUG || defined(NAZARA_DEBUG)
bool NzContextParameters::defaultDebugMode = true;
#else
bool NzContextParameters::defaultDebugMode = false;
#endif
bool NzContextParameters::defaultDoubleBuffered = false; bool NzContextParameters::defaultDoubleBuffered = false;
bool NzContextParameters::defaultShared = true; bool NzContextParameters::defaultShared = true;

View File

@ -122,10 +122,82 @@ bool NzOpenGL::Initialize()
parameters.minorVersion = 0; parameters.minorVersion = 0;
parameters.shared = false; parameters.shared = false;
/*
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.
Non sérieusement si quelqu'un a une meilleure idée qu'il me le dise
*/
/****************************************Initialisation****************************************/
NzContext loadContext; NzContext loadContext;
if (!loadContext.Create(parameters)) if (!loadContext.Create(parameters))
{ {
NazaraError("Failed to create load context"); NazaraError("Failed to create load context");
Uninitialize();
return false;
}
#if defined(NAZARA_PLATFORM_WINDOWS)
wglCreateContextAttribs = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(LoadEntry("wglCreateContextAttribsARB", false));
wglChoosePixelFormat = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(LoadEntry("wglChoosePixelFormatARB", false));
if (!wglChoosePixelFormat)
wglChoosePixelFormat = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATEXTPROC>(LoadEntry("wglChoosePixelFormatEXT", false));
#elif defined(NAZARA_PLATFORM_LINUX)
glXCreateContextAttribs = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(LoadEntry("glXCreateContextAttribsARB", false));
#endif
// Récupération de la version d'OpenGL
// Ce code se base sur le fait que la carte graphique renverra un contexte de compatibilité avec la plus haute version supportée
// Ce qui semble vrai au moins chez ATI/AMD et NVidia, mais si quelqu'un à une meilleure idée ...
glGetString = reinterpret_cast<PFNGLGETSTRINGPROC>(LoadEntry("glGetString"));
if (!glGetString)
{
NazaraError("Unable to load OpenGL: failed to load glGetString");
Uninitialize();
return false;
}
const GLubyte* version = glGetString(GL_VERSION);
if (!version)
{
NazaraError("Unable to retrieve OpenGL version");
Uninitialize();
return false;
}
unsigned int major = version[0] - '0';
unsigned int minor = version[2] - '0';
if (major == 0 || major > 9)
{
NazaraError("Unable to retrieve OpenGL major version");
return false;
}
if (minor > 9)
{
NazaraWarning("Unable to retrieve OpenGL minor version (using 0)");
minor = 0;
}
openGLversion = major*100 + minor*10;
parameters.debugMode = true; // Certaines extensions n'apparaissent qu'avec un contexte de debug (e.g. ARB_debug_output)
parameters.majorVersion = NzContextParameters::defaultMajorVersion = openGLversion/100;
parameters.minorVersion = NzContextParameters::defaultMinorVersion = (openGLversion%100)/10;
// Destruction implicite du premier contexte
if (!loadContext.Create(parameters))
{
NazaraError("Failed to create load context");
Uninitialize();
return false; return false;
} }
@ -182,7 +254,6 @@ bool NzOpenGL::Initialize()
glGetShaderInfoLog = reinterpret_cast<PFNGLGETSHADERINFOLOGPROC>(LoadEntry("glGetShaderInfoLog")); glGetShaderInfoLog = reinterpret_cast<PFNGLGETSHADERINFOLOGPROC>(LoadEntry("glGetShaderInfoLog"));
glGetShaderiv = reinterpret_cast<PFNGLGETSHADERIVPROC>(LoadEntry("glGetShaderiv")); glGetShaderiv = reinterpret_cast<PFNGLGETSHADERIVPROC>(LoadEntry("glGetShaderiv"));
glGetShaderSource = reinterpret_cast<PFNGLGETSHADERSOURCEPROC>(LoadEntry("glGetShaderSource")); glGetShaderSource = reinterpret_cast<PFNGLGETSHADERSOURCEPROC>(LoadEntry("glGetShaderSource"));
glGetString = reinterpret_cast<PFNGLGETSTRINGPROC>(LoadEntry("glGetString"));
glGetTexImage = reinterpret_cast<PFNGLGETTEXIMAGEPROC>(LoadEntry("glGetTexImage")); glGetTexImage = reinterpret_cast<PFNGLGETTEXIMAGEPROC>(LoadEntry("glGetTexImage"));
glGetTexParameterfv = reinterpret_cast<PFNGLGETTEXPARAMETERFVPROC>(LoadEntry("glGetTexParameterfv")); glGetTexParameterfv = reinterpret_cast<PFNGLGETTEXPARAMETERFVPROC>(LoadEntry("glGetTexParameterfv"));
glGetTexParameteriv = reinterpret_cast<PFNGLGETTEXPARAMETERIVPROC>(LoadEntry("glGetTexParameteriv")); glGetTexParameteriv = reinterpret_cast<PFNGLGETTEXPARAMETERIVPROC>(LoadEntry("glGetTexParameteriv"));
@ -223,50 +294,13 @@ bool NzOpenGL::Initialize()
glMapBufferRange = reinterpret_cast<PFNGLMAPBUFFERRANGEPROC>(LoadEntry("glMapBufferRange", false)); glMapBufferRange = reinterpret_cast<PFNGLMAPBUFFERRANGEPROC>(LoadEntry("glMapBufferRange", false));
#if defined(NAZARA_PLATFORM_WINDOWS) #if defined(NAZARA_PLATFORM_WINDOWS)
wglCreateContextAttribs = reinterpret_cast<PFNWGLCREATECONTEXTATTRIBSARBPROC>(LoadEntry("wglCreateContextAttribsARB", false));
wglChoosePixelFormat = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATARBPROC>(LoadEntry("wglChoosePixelFormatARB", false));
if (!wglChoosePixelFormat)
wglChoosePixelFormat = reinterpret_cast<PFNWGLCHOOSEPIXELFORMATEXTPROC>(LoadEntry("wglChoosePixelFormatEXT", false));
wglGetExtensionsStringARB = reinterpret_cast<PFNWGLGETEXTENSIONSSTRINGARBPROC>(LoadEntry("wglGetExtensionsStringARB", false)); wglGetExtensionsStringARB = reinterpret_cast<PFNWGLGETEXTENSIONSSTRINGARBPROC>(LoadEntry("wglGetExtensionsStringARB", false));
wglGetExtensionsStringEXT = reinterpret_cast<PFNWGLGETEXTENSIONSSTRINGEXTPROC>(LoadEntry("wglGetExtensionsStringEXT", false)); wglGetExtensionsStringEXT = reinterpret_cast<PFNWGLGETEXTENSIONSSTRINGEXTPROC>(LoadEntry("wglGetExtensionsStringEXT", false));
wglSwapInterval = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(LoadEntry("wglSwapIntervalEXT", false)); wglSwapInterval = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(LoadEntry("wglSwapIntervalEXT", false));
#elif defined(NAZARA_PLATFORM_LINUX) #elif defined(NAZARA_PLATFORM_LINUX)
glXCreateContextAttribs = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(LoadEntry("glXCreateContextAttribsARB", false));
glXSwapInterval = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(LoadEntry("glXSwapIntervalSGI", false)); glXSwapInterval = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(LoadEntry("glXSwapIntervalSGI", false));
#endif #endif
// Récupération de la version d'OpenGL
// Ce code se base sur le fait que la carte graphique renverra un contexte de compatibilité avec la plus haute version supportée
// Ce qui semble vrai au moins chez ATI/AMD et NVidia, mais si quelqu'un à une meilleure idée ...
const GLubyte* version = glGetString(GL_VERSION);
if (!version)
{
NazaraError("Unable to retrieve OpenGL version");
Uninitialize();
return false;
}
unsigned int major = version[0] - '0';
unsigned int minor = version[2] - '0';
if (major == 0 || major > 9)
{
NazaraError("Unable to retrieve OpenGL major version");
Uninitialize();
return false;
}
if (minor > 9)
{
NazaraWarning("Unable to retrieve OpenGL minor version (using 0)");
minor = 0;
}
openGLversion = major*100 + minor*10;
/****************************************Extensions****************************************/ /****************************************Extensions****************************************/
if (!glGetStringi || !LoadExtensions3()) if (!glGetStringi || !LoadExtensions3())
@ -296,6 +330,24 @@ bool NzOpenGL::Initialize()
// AnisotropicFilter // AnisotropicFilter
openGLextensions[NzOpenGL::AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic"); openGLextensions[NzOpenGL::AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic");
// DebugOutput
if (IsSupported("GL_ARB_debug_output"))
{
try
{
glDebugMessageControl = reinterpret_cast<PFNGLDEBUGMESSAGECONTROLARBPROC>(LoadEntry("glDebugMessageControlARB"));
glDebugMessageInsert = reinterpret_cast<PFNGLDEBUGMESSAGEINSERTARBPROC>(LoadEntry("glDebugMessageInsertARB"));
glDebugMessageCallback = reinterpret_cast<PFNGLDEBUGMESSAGECALLBACKARBPROC>(LoadEntry("glDebugMessageCallbackARB"));
glGetDebugMessageLog = reinterpret_cast<PFNGLGETDEBUGMESSAGELOGARBPROC>(LoadEntry("glGetDebugMessageLogARB"));
openGLextensions[NzOpenGL::DebugOutput] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load GL_ARB_debug_output: " + NzString(e.what()));
}
}
// FP64 // FP64
if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64")) if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64"))
{ {
@ -362,11 +414,26 @@ bool NzOpenGL::Initialize()
} }
// Texture3D // Texture3D
try
{
glTexImage3D = reinterpret_cast<PFNGLTEXIMAGE3DPROC>(LoadEntry("glTexImage3D"));
glTexSubImage3D = reinterpret_cast<PFNGLTEXSUBIMAGE3DPROC>(LoadEntry("glTexSubImage3D"));
openGLextensions[NzOpenGL::Texture3D] = true;
}
catch (const std::exception& e)
{
if (openGLversion >= 120)
NazaraWarning("Failed to load core texture 3D (" + NzString(e.what()) + ")");
if (IsSupported("GL_EXT_texture3D")) if (IsSupported("GL_EXT_texture3D"))
{ {
try try
{ {
glTexImage3D = reinterpret_cast<PFNGLTEXIMAGE3DEXTPROC>(LoadEntry("glTexImage3DEXT")); // Hacky: Normalement incompatible à cause du internalFormat, GLenum pour l'extension et GLint pour le noyau
// Mais la taille du type étant la même (GLenum est un typedef équivalent à GLint) et Nazara n'utilisant pas
// Ce qui cause l'incompatibilité (les paramètres 1,2,3,4), je prends cette liberté
glTexImage3D = reinterpret_cast<PFNGLTEXIMAGE3DPROC>(LoadEntry("glTexImage3DEXT"));
glTexSubImage3D = reinterpret_cast<PFNGLTEXSUBIMAGE3DEXTPROC>(LoadEntry("glTexSubImage3DEXT")); glTexSubImage3D = reinterpret_cast<PFNGLTEXSUBIMAGE3DEXTPROC>(LoadEntry("glTexSubImage3DEXT"));
openGLextensions[NzOpenGL::Texture3D] = true; openGLextensions[NzOpenGL::Texture3D] = true;
@ -376,15 +443,33 @@ bool NzOpenGL::Initialize()
NazaraError("Failed to load EXT_texture3D: " + NzString(e.what())); NazaraError("Failed to load EXT_texture3D: " + NzString(e.what()));
} }
} }
}
// VertexArrayObject
if (openGLversion >= 420 || IsSupported("GL_ARB_texture_storage"))
{
try
{
glTexStorage1D = reinterpret_cast<PFNGLTEXSTORAGE1DPROC>(LoadEntry("glTexStorage1D"));
glTexStorage2D = reinterpret_cast<PFNGLTEXSTORAGE2DPROC>(LoadEntry("glTexStorage2D"));
glTexStorage3D = reinterpret_cast<PFNGLTEXSTORAGE3DPROC>(LoadEntry("glTexStorage3D"));
openGLextensions[NzOpenGL::TextureStorage] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load ARB_texture_storage: " + NzString(e.what()));
}
}
// VertexArrayObject // VertexArrayObject
if (openGLversion >= 300 || IsSupported("GL_ARB_vertex_array_object")) if (openGLversion >= 300 || IsSupported("GL_ARB_vertex_array_object"))
{ {
try try
{ {
glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(LoadEntry("glBindVertexArray", false)); glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(LoadEntry("glBindVertexArray"));
glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(LoadEntry("glDeleteVertexArrays", false)); glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(LoadEntry("glDeleteVertexArrays"));
glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(LoadEntry("glGenVertexArrays", false)); glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(LoadEntry("glGenVertexArrays"));
openGLextensions[NzOpenGL::VertexArrayObject] = true; openGLextensions[NzOpenGL::VertexArrayObject] = true;
} }
@ -394,11 +479,9 @@ bool NzOpenGL::Initialize()
} }
} }
/****************************************Contextes****************************************/ /****************************************Contexte de référence****************************************/
NzContextParameters::defaultMajorVersion = openGLversion/100;
NzContextParameters::defaultMinorVersion = (openGLversion%100)/10;
///FIXME: Utiliser le contexte de chargement comme référence ? (Vérifier mode debug)
if (!NzContext::InitializeReference()) if (!NzContext::InitializeReference())
{ {
NazaraError("Failed to initialize reference context"); NazaraError("Failed to initialize reference context");
@ -457,6 +540,9 @@ PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = nullptr;
PFNGLCOLORMASKPROC glColorMask = nullptr; PFNGLCOLORMASKPROC glColorMask = nullptr;
PFNGLCULLFACEPROC glCullFace = nullptr; PFNGLCULLFACEPROC glCullFace = nullptr;
PFNGLCOMPILESHADERPROC glCompileShader = nullptr; PFNGLCOMPILESHADERPROC glCompileShader = nullptr;
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControl = nullptr;
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsert = nullptr;
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallback = nullptr;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr; PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = nullptr; PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = nullptr;
PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr; PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr;
@ -487,6 +573,7 @@ PFNGLGENQUERIESPROC glGenQueries = nullptr;
PFNGLGENTEXTURESPROC glGenTextures = nullptr; PFNGLGENTEXTURESPROC glGenTextures = nullptr;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr; PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr;
PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr; PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr;
PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLog = nullptr;
PFNGLGETERRORPROC glGetError = nullptr; PFNGLGETERRORPROC glGetError = nullptr;
PFNGLGETINTEGERVPROC glGetIntegerv = nullptr; PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr; PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
@ -512,12 +599,17 @@ PFNGLSCISSORPROC glScissor = nullptr;
PFNGLSHADERSOURCEPROC glShaderSource = nullptr; PFNGLSHADERSOURCEPROC glShaderSource = nullptr;
PFNGLSTENCILFUNCPROC glStencilFunc = nullptr; PFNGLSTENCILFUNCPROC glStencilFunc = nullptr;
PFNGLSTENCILOPPROC glStencilOp = nullptr; PFNGLSTENCILOPPROC glStencilOp = nullptr;
PFNGLTEXIMAGE1DPROC glTexImage1D = nullptr;
PFNGLTEXIMAGE2DPROC glTexImage2D = nullptr; PFNGLTEXIMAGE2DPROC glTexImage2D = nullptr;
PFNGLTEXIMAGE3DEXTPROC glTexImage3D = nullptr; PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr;
PFNGLTEXPARAMETERFPROC glTexParameterf = nullptr; PFNGLTEXPARAMETERFPROC glTexParameterf = nullptr;
PFNGLTEXPARAMETERIPROC glTexParameteri = nullptr; PFNGLTEXPARAMETERIPROC glTexParameteri = nullptr;
PFNGLTEXSTORAGE1DPROC glTexStorage1D = nullptr;
PFNGLTEXSTORAGE2DPROC glTexStorage2D = nullptr;
PFNGLTEXSTORAGE3DPROC glTexStorage3D = nullptr;
PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D = nullptr;
PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D = nullptr; PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D = nullptr;
PFNGLTEXSUBIMAGE3DEXTPROC glTexSubImage3D = nullptr; PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr;
PFNGLUNIFORM1DPROC glUniform1d = nullptr; PFNGLUNIFORM1DPROC glUniform1d = nullptr;
PFNGLUNIFORM1FPROC glUniform1f = nullptr; PFNGLUNIFORM1FPROC glUniform1f = nullptr;
PFNGLUNIFORM1IPROC glUniform1i = nullptr; PFNGLUNIFORM1IPROC glUniform1i = nullptr;

View File

@ -460,17 +460,20 @@ bool NzRenderer::UpdateStates()
if (vaoSupported) if (vaoSupported)
{ {
// On recherche si un VAO existe déjà avec notre configuration // On recherche si un VAO existe déjà avec notre configuration
// Note: Les VAOs ne sont pas partagés entre les contextes, ils font donc partie de notre configuration // Note: Les VAOs ne sont pas partagés entre les contextes, ces derniers font donc partie de notre configuration
auto key = std::make_tuple(NzContext::GetCurrent(), m_indexBuffer, m_vertexBuffer, m_vertexDeclaration); auto key = std::make_tuple(NzContext::GetCurrent(), m_indexBuffer, m_vertexBuffer, m_vertexDeclaration);
auto it = m_vaos.find(key); auto it = m_vaos.find(key);
if (it == m_vaos.end()) if (it == m_vaos.end())
{ {
// On créé notre VAO
glGenVertexArrays(1, &vao); glGenVertexArrays(1, &vao);
glBindVertexArray(vao); glBindVertexArray(vao);
// On l'ajoute à notre liste
m_vaos.insert(std::make_pair(key, static_cast<unsigned int>(vao))); m_vaos.insert(std::make_pair(key, static_cast<unsigned int>(vao)));
// Et on indique qu'on veut le programmer
update = true; update = true;
} }
else else

View File

@ -153,6 +153,8 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
*attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB; *attrib++ = WGL_CONTEXT_MINOR_VERSION_ARB;
*attrib++ = parameters.minorVersion; *attrib++ = parameters.minorVersion;
int flags = 0;
if (parameters.majorVersion >= 3) if (parameters.majorVersion >= 3)
{ {
*attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB; *attrib++ = WGL_CONTEXT_PROFILE_MASK_ARB;
@ -162,11 +164,19 @@ bool NzContextImpl::Create(NzContextParameters& parameters)
{ {
*attrib++ = WGL_CONTEXT_CORE_PROFILE_BIT_ARB; *attrib++ = WGL_CONTEXT_CORE_PROFILE_BIT_ARB;
*attrib++ = WGL_CONTEXT_FLAGS_ARB; flags |= WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
*attrib++ = WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB;
} }
} }
if (parameters.debugMode)
flags |= WGL_CONTEXT_DEBUG_BIT_ARB;
if (flags)
{
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
*attrib++ = flags;
}
*attrib++ = 0; *attrib++ = 0;
m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes); m_context = wglCreateContextAttribs(m_deviceContext, shareContext, attributes);