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>
#define NazaraLog NzLog::Instance()
#define NazaraNotice(txt) NazaraLog->Write(txt)
class NzFile;

View File

@ -38,6 +38,9 @@
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
#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)
#define NAZARA_RENDERER_SAFE 1

View File

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

View File

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

View File

@ -34,9 +34,11 @@ class NAZARA_API NzOpenGL
enum Extension
{
AnisotropicFilter,
DebugOutput,
FP64,
FrameBufferObject,
Texture3D,
TextureStorage,
VertexArrayObject,
Count
@ -71,6 +73,9 @@ NAZARA_API extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus;
NAZARA_API extern PFNGLCOLORMASKPROC glColorMask;
NAZARA_API extern PFNGLCULLFACEPROC glCullFace;
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 PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
NAZARA_API extern PFNGLDELETEPROGRAMPROC glDeleteProgram;
@ -101,6 +106,7 @@ NAZARA_API extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers;
NAZARA_API extern PFNGLGENTEXTURESPROC glGenTextures;
NAZARA_API extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
NAZARA_API extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv;
NAZARA_API extern PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLog;
NAZARA_API extern PFNGLGETERRORPROC glGetError;
NAZARA_API extern PFNGLGETINTEGERVPROC glGetIntegerv;
NAZARA_API extern PFNGLGETPROGRAMIVPROC glGetProgramiv;
@ -126,12 +132,17 @@ NAZARA_API extern PFNGLSCISSORPROC glScissor;
NAZARA_API extern PFNGLSHADERSOURCEPROC glShaderSource;
NAZARA_API extern PFNGLSTENCILFUNCPROC glStencilFunc;
NAZARA_API extern PFNGLSTENCILOPPROC glStencilOp;
NAZARA_API extern PFNGLTEXIMAGE1DPROC glTexImage1D;
NAZARA_API extern PFNGLTEXIMAGE2DPROC glTexImage2D;
NAZARA_API extern PFNGLTEXIMAGE3DEXTPROC glTexImage3D;
NAZARA_API extern PFNGLTEXIMAGE3DPROC glTexImage3D;
NAZARA_API extern PFNGLTEXPARAMETERFPROC glTexParameterf;
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 PFNGLTEXSUBIMAGE3DEXTPROC glTexSubImage3D;
NAZARA_API extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D;
NAZARA_API extern PFNGLUNIFORM1DPROC glUniform1d;
NAZARA_API extern PFNGLUNIFORM1FPROC glUniform1f;
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)
{
unsigned int size = sizeof(ptr)*2;
unsigned int size = sizeof(ptr)*2+2;
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));
}

View File

@ -5,6 +5,8 @@
#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>
#if defined(NAZARA_PLATFORM_WINDOWS)
@ -22,6 +24,108 @@ namespace
///TODO: Thread-local
NzContext* currentContext = 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() :
@ -31,18 +135,13 @@ m_impl(nullptr)
NzContext::~NzContext()
{
if (m_impl)
{
if (currentContext == this)
NzContextImpl::Desactivate();
m_impl->Destroy();
delete m_impl;
}
Destroy();
}
bool NzContext::Create(const NzContextParameters& parameters)
{
Destroy();
m_parameters = parameters;
if (m_parameters.shared && !m_parameters.shareContext)
m_parameters.shareContext = s_reference;
@ -71,9 +170,30 @@ bool NzContext::Create(const NzContextParameters& parameters)
if (m_parameters.antialiasingLevel > 0)
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;
}
void NzContext::Destroy()
{
if (m_impl)
{
if (currentContext == this)
NzContextImpl::Desactivate();
m_impl->Destroy();
delete m_impl;
}
}
const NzContextParameters& NzContext::GetParameters() const
{
#ifdef NAZARA_RENDERER_SAFE

View File

@ -3,6 +3,7 @@
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Renderer/ContextParameters.hpp>
#include <Nazara/Renderer/Config.hpp>
#include <Nazara/Renderer/Debug.hpp>
nzUInt8 NzContextParameters::defaultMajorVersion; // Initialisé par NzOpenGL
@ -10,5 +11,10 @@ nzUInt8 NzContextParameters::defaultMinorVersion; // Initialis
const NzContext* NzContextParameters::defaultShareContext = nullptr;
NzWindowHandle NzContextParameters::defaultWindow = 0;
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::defaultShared = true;

View File

@ -122,10 +122,82 @@ bool NzOpenGL::Initialize()
parameters.minorVersion = 0;
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;
if (!loadContext.Create(parameters))
{
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;
}
@ -182,7 +254,6 @@ bool NzOpenGL::Initialize()
glGetShaderInfoLog = reinterpret_cast<PFNGLGETSHADERINFOLOGPROC>(LoadEntry("glGetShaderInfoLog"));
glGetShaderiv = reinterpret_cast<PFNGLGETSHADERIVPROC>(LoadEntry("glGetShaderiv"));
glGetShaderSource = reinterpret_cast<PFNGLGETSHADERSOURCEPROC>(LoadEntry("glGetShaderSource"));
glGetString = reinterpret_cast<PFNGLGETSTRINGPROC>(LoadEntry("glGetString"));
glGetTexImage = reinterpret_cast<PFNGLGETTEXIMAGEPROC>(LoadEntry("glGetTexImage"));
glGetTexParameterfv = reinterpret_cast<PFNGLGETTEXPARAMETERFVPROC>(LoadEntry("glGetTexParameterfv"));
glGetTexParameteriv = reinterpret_cast<PFNGLGETTEXPARAMETERIVPROC>(LoadEntry("glGetTexParameteriv"));
@ -223,50 +294,13 @@ bool NzOpenGL::Initialize()
glMapBufferRange = reinterpret_cast<PFNGLMAPBUFFERRANGEPROC>(LoadEntry("glMapBufferRange", 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));
wglGetExtensionsStringARB = reinterpret_cast<PFNWGLGETEXTENSIONSSTRINGARBPROC>(LoadEntry("wglGetExtensionsStringARB", false));
wglGetExtensionsStringEXT = reinterpret_cast<PFNWGLGETEXTENSIONSSTRINGEXTPROC>(LoadEntry("wglGetExtensionsStringEXT", false));
wglSwapInterval = reinterpret_cast<PFNWGLSWAPINTERVALEXTPROC>(LoadEntry("wglSwapIntervalEXT", false));
#elif defined(NAZARA_PLATFORM_LINUX)
glXCreateContextAttribs = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(LoadEntry("glXCreateContextAttribsARB", false));
glXSwapInterval = reinterpret_cast<PFNGLXSWAPINTERVALSGIPROC>(LoadEntry("glXSwapIntervalSGI", 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 ...
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****************************************/
if (!glGetStringi || !LoadExtensions3())
@ -296,6 +330,24 @@ bool NzOpenGL::Initialize()
// AnisotropicFilter
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
if (openGLversion >= 400 || IsSupported("GL_ARB_gpu_shader_fp64"))
{
@ -362,18 +414,51 @@ bool NzOpenGL::Initialize()
}
// Texture3D
if (IsSupported("GL_EXT_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"))
{
try
{
// 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"));
openGLextensions[NzOpenGL::Texture3D] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load EXT_texture3D: " + NzString(e.what()));
}
}
}
// VertexArrayObject
if (openGLversion >= 420 || IsSupported("GL_ARB_texture_storage"))
{
try
{
glTexImage3D = reinterpret_cast<PFNGLTEXIMAGE3DEXTPROC>(LoadEntry("glTexImage3DEXT"));
glTexSubImage3D = reinterpret_cast<PFNGLTEXSUBIMAGE3DEXTPROC>(LoadEntry("glTexSubImage3DEXT"));
glTexStorage1D = reinterpret_cast<PFNGLTEXSTORAGE1DPROC>(LoadEntry("glTexStorage1D"));
glTexStorage2D = reinterpret_cast<PFNGLTEXSTORAGE2DPROC>(LoadEntry("glTexStorage2D"));
glTexStorage3D = reinterpret_cast<PFNGLTEXSTORAGE3DPROC>(LoadEntry("glTexStorage3D"));
openGLextensions[NzOpenGL::Texture3D] = true;
openGLextensions[NzOpenGL::TextureStorage] = true;
}
catch (const std::exception& e)
{
NazaraError("Failed to load EXT_texture3D: " + NzString(e.what()));
NazaraError("Failed to load ARB_texture_storage: " + NzString(e.what()));
}
}
@ -382,9 +467,9 @@ bool NzOpenGL::Initialize()
{
try
{
glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(LoadEntry("glBindVertexArray", false));
glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(LoadEntry("glDeleteVertexArrays", false));
glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(LoadEntry("glGenVertexArrays", false));
glBindVertexArray = reinterpret_cast<PFNGLBINDVERTEXARRAYPROC>(LoadEntry("glBindVertexArray"));
glDeleteVertexArrays = reinterpret_cast<PFNGLDELETEVERTEXARRAYSPROC>(LoadEntry("glDeleteVertexArrays"));
glGenVertexArrays = reinterpret_cast<PFNGLGENVERTEXARRAYSPROC>(LoadEntry("glGenVertexArrays"));
openGLextensions[NzOpenGL::VertexArrayObject] = true;
}
@ -394,11 +479,9 @@ bool NzOpenGL::Initialize()
}
}
/****************************************Contextes****************************************/
NzContextParameters::defaultMajorVersion = openGLversion/100;
NzContextParameters::defaultMinorVersion = (openGLversion%100)/10;
/****************************************Contexte de référence****************************************/
///FIXME: Utiliser le contexte de chargement comme référence ? (Vérifier mode debug)
if (!NzContext::InitializeReference())
{
NazaraError("Failed to initialize reference context");
@ -457,6 +540,9 @@ PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = nullptr;
PFNGLCOLORMASKPROC glColorMask = nullptr;
PFNGLCULLFACEPROC glCullFace = nullptr;
PFNGLCOMPILESHADERPROC glCompileShader = nullptr;
PFNGLDEBUGMESSAGECONTROLARBPROC glDebugMessageControl = nullptr;
PFNGLDEBUGMESSAGEINSERTARBPROC glDebugMessageInsert = nullptr;
PFNGLDEBUGMESSAGECALLBACKARBPROC glDebugMessageCallback = nullptr;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = nullptr;
PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr;
@ -487,6 +573,7 @@ PFNGLGENQUERIESPROC glGenQueries = nullptr;
PFNGLGENTEXTURESPROC glGenTextures = nullptr;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr;
PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr;
PFNGLGETDEBUGMESSAGELOGARBPROC glGetDebugMessageLog = nullptr;
PFNGLGETERRORPROC glGetError = nullptr;
PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
@ -512,12 +599,17 @@ PFNGLSCISSORPROC glScissor = nullptr;
PFNGLSHADERSOURCEPROC glShaderSource = nullptr;
PFNGLSTENCILFUNCPROC glStencilFunc = nullptr;
PFNGLSTENCILOPPROC glStencilOp = nullptr;
PFNGLTEXIMAGE1DPROC glTexImage1D = nullptr;
PFNGLTEXIMAGE2DPROC glTexImage2D = nullptr;
PFNGLTEXIMAGE3DEXTPROC glTexImage3D = nullptr;
PFNGLTEXIMAGE3DPROC glTexImage3D = nullptr;
PFNGLTEXPARAMETERFPROC glTexParameterf = nullptr;
PFNGLTEXPARAMETERIPROC glTexParameteri = nullptr;
PFNGLTEXSTORAGE1DPROC glTexStorage1D = nullptr;
PFNGLTEXSTORAGE2DPROC glTexStorage2D = nullptr;
PFNGLTEXSTORAGE3DPROC glTexStorage3D = nullptr;
PFNGLTEXSUBIMAGE1DPROC glTexSubImage1D = nullptr;
PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D = nullptr;
PFNGLTEXSUBIMAGE3DEXTPROC glTexSubImage3D = nullptr;
PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr;
PFNGLUNIFORM1DPROC glUniform1d = nullptr;
PFNGLUNIFORM1FPROC glUniform1f = nullptr;
PFNGLUNIFORM1IPROC glUniform1i = nullptr;

View File

@ -460,17 +460,20 @@ bool NzRenderer::UpdateStates()
if (vaoSupported)
{
// 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 it = m_vaos.find(key);
if (it == m_vaos.end())
{
// On créé notre VAO
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// On l'ajoute à notre liste
m_vaos.insert(std::make_pair(key, static_cast<unsigned int>(vao)));
// Et on indique qu'on veut le programmer
update = true;
}
else

View File

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