Revert Renderer to its pre-SDL state

This commit is contained in:
Lynix
2020-05-27 19:42:53 +02:00
parent 2d189dc85e
commit 81f03f04e5
12 changed files with 1148 additions and 595 deletions

View File

@@ -48,17 +48,17 @@ namespace Nz
}
WindowImpl::WindowImpl(Window* parent) :
m_cursor(nullptr),
m_handle(nullptr),
//m_callback(0),
m_style(0),
m_maxSize(-1),
m_minSize(-1),
m_parent(parent),
m_keyRepeat(true),
m_mouseInside(false),
m_smoothScrolling(false),
m_scrolling(0)
m_cursor(nullptr),
m_handle(nullptr),
//m_callback(0),
m_style(0),
m_maxSize(-1),
m_minSize(-1),
m_parent(parent),
m_keyRepeat(true),
m_mouseInside(false),
m_smoothScrolling(false),
m_scrolling(0)
{
m_cursor = SDL_GetDefaultCursor();
}
@@ -76,7 +76,7 @@ namespace Nz
bool fullscreen = (style & WindowStyle_Fullscreen) != 0;
Uint32 winStyle = SDL_WINDOW_OPENGL;
Uint32 winStyle = 0;
unsigned int x, y;
unsigned int width = mode.width;
@@ -147,19 +147,18 @@ namespace Nz
m_size.Set(width, height);
SDL_AddEventWatch(HandleEvent, this);
return true;
}
void WindowImpl::Destroy()
{
if (m_ownsWindow && m_handle)
{
SDL_DelEventWatch(HandleEvent, this);
SDL_DestroyWindow(m_handle);
}
else
SetEventListener(false);
SDL_DelEventWatch(HandleEvent, this);
}
void WindowImpl::EnableKeyRepeat(bool enable)
@@ -195,6 +194,8 @@ namespace Nz
WindowHandle WindowImpl::GetSystemHandle() const
{
SDL_SysWMinfo wmInfo;
SDL_VERSION(&wmInfo.version);
if (SDL_GetWindowWMInfo(m_handle, &wmInfo) != SDL_TRUE)
{
ErrorFlags flags(ErrorFlag_ThrowException, true);
@@ -545,7 +546,13 @@ namespace Nz
void WindowImpl::SetEventListener(bool listener)
{
if (m_ownsWindow)
return;
if (listener)
SDL_AddEventWatch(HandleEvent, this);
else
SDL_DelEventWatch(HandleEvent, this);
}
void WindowImpl::SetFocus()
@@ -613,16 +620,6 @@ namespace Nz
NazaraError(SDL_GetError());
return false;
}
if (SDL_GL_LoadLibrary(nullptr) < 0)
{
NazaraError(SDL_GetError());
SDL_Quit();
return false;
}
if (SDL_GL_SetAttribute(SDL_GL_SHARE_WITH_CURRENT_CONTEXT, true) < 0)
NazaraError("Couldn't set share OpenGL contexes");
return true;
}

View File

@@ -12,10 +12,13 @@
#include <memory>
#include <vector>
#include <Nazara/Renderer/SDL2/ContextImpl.hpp>
#if defined(NAZARA_PLATFORM_LINUX)
#if defined(NAZARA_PLATFORM_WINDOWS)
#include <Nazara/Renderer/Win32/ContextImpl.hpp>
#elif defined(NAZARA_PLATFORM_GLX)
#include <Nazara/Renderer/GLX/ContextImpl.hpp>
#define CALLBACK
#else
#error Lack of implementation: Context
#endif
#include <Nazara/Renderer/Debug.hpp>

View File

@@ -0,0 +1,302 @@
// Copyright (C) 2015 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/GLX/ContextImpl.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Debug.hpp>
using namespace GLX;
namespace Nz
{
namespace
{
Display* m_display;
int m_sharedDisplay = 0;
bool ctxErrorOccurred = false;
int ctxErrorHandler( Display* /*dpy*/, XErrorEvent* /*ev*/ )
{
ctxErrorOccurred = true;
return 0;
}
}
ContextImpl::ContextImpl() :
m_colormap(0),
m_context(0),
m_window(0),
m_ownsWindow(false)
{
if (m_sharedDisplay == 0)
m_display = XOpenDisplay(nullptr);
++m_sharedDisplay;
}
ContextImpl::~ContextImpl()
{
Destroy();
if (--m_sharedDisplay == 0)
{
XCloseDisplay(m_display);
m_display = nullptr;
}
}
bool ContextImpl::Activate() const
{
return glXMakeCurrent(m_display, m_window, m_context) == true;
}
bool ContextImpl::Create(ContextParameters& parameters)
{
// En cas d'exception, la ressource sera quand même libérée
CallOnExit onExit([this] ()
{
Destroy();
});
// Get a matching FB config
static int visual_attribs[] =
{
GLX_X_RENDERABLE, True,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_BUFFER_SIZE, parameters.bitsPerPixel,
GLX_ALPHA_SIZE, (parameters.bitsPerPixel == 32) ? 8 : 0,
GLX_DEPTH_SIZE, parameters.depthBits,
GLX_STENCIL_SIZE, parameters.stencilBits,
GLX_DOUBLEBUFFER, True,
GLX_SAMPLE_BUFFERS, (parameters.antialiasingLevel > 0) ? True : False,
GLX_SAMPLES, parameters.antialiasingLevel,
None
};
int glx_major = 0;
int glx_minor = 0;
// FBConfigs were added in GLX version 1.3.
if (!glXQueryVersion(m_display, &glx_major, &glx_minor) || ((glx_major == 1) && (glx_minor < 3)) || (glx_major < 1))
{
NazaraError("Invalid GLX version, version > 1.3 is required.");
return false;
}
int fbcount;
GLXFBConfig* fbc = glXChooseFBConfig(m_display, XDefaultScreen(m_display), visual_attribs, &fbcount);
if (!fbc)
{
NazaraError("Failed to retrieve a framebuffer config");
return false;
}
// Pick the FB config/visual with the most samples per pixel
int best_fbc = -1;
int worst_fbc = -1;
int best_num_samp = -1;
int worst_num_samp = 999;
for (int i = 0; i < fbcount; ++i)
{
XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, fbc[i]);
if (vi)
{
int samp_buf = 0, samples = 0;
glXGetFBConfigAttrib(m_display, fbc[i], GLX_SAMPLE_BUFFERS, &samp_buf);
glXGetFBConfigAttrib(m_display, fbc[i], GLX_SAMPLES , &samples );
if ((best_fbc < 0) || (samp_buf && (samples > best_num_samp)))
{
best_fbc = i;
best_num_samp = samples;
}
if ((worst_fbc < 0) || !samp_buf || (samples < worst_num_samp))
{
worst_fbc = i;
worst_num_samp = samples;
}
}
XFree(vi);
}
GLXFBConfig bestFbc = fbc[best_fbc];
// Be sure to free the FBConfig list allocated by glXChooseFBConfig()
XFree(fbc);
// Get a visual
XVisualInfo* vi = glXGetVisualFromFBConfig(m_display, bestFbc);
if (!vi)
{
NazaraError("Failed to get best VisualInfo");
return false;
}
// If context is shared by multiple windows
if (parameters.window)
{
NazaraAssert(parameters.window.type == WindowManager::X11, "Cannot create a context for a non-x11 window");
m_window = static_cast<GLX::Window>(parameters.window.x11.window);
m_ownsWindow = false;
}
else
{
XSetWindowAttributes swa;
swa.colormap = m_colormap = XCreateColormap(
m_display,
XRootWindow(
m_display,
vi->screen),
vi->visual,
AllocNone
);
swa.background_pixmap = None;
swa.border_pixel = 0;
swa.event_mask = StructureNotifyMask;
if (!m_colormap)
{
NazaraError("Failed to create colormap for context");
return false;
}
m_window = XCreateWindow(
m_display,
XRootWindow(
m_display,
vi->screen),
0, 0, // X, Y
1, 1, // W H
0,
vi->depth,
InputOutput,
vi->visual,
CWBorderPixel | CWColormap | CWEventMask,
&swa
);
m_ownsWindow = true;
}
if (!m_window)
{
NazaraError("Failed to create window");
return false;
}
// Done with the visual info data
XFree(vi);
// Install an X error handler so the application won't exit if GL 3.0
// context allocation fails.
//
// Note this error handler is global. All display connections in all threads
// of a process use the same error handler, so be sure to guard against other
// threads issuing X commands while this code is running.
ctxErrorOccurred = false;
int (*oldHandler)(Display*, XErrorEvent*) =
XSetErrorHandler(&ctxErrorHandler);
// Check for the GLX_ARB_create_context extension string and the function.
// If either is not present, use GLX 1.3 context creation method.
if (!glXCreateContextAttribs)
{
NazaraWarning("glXCreateContextAttribs() not found. Using old-style GLX context");
m_context = glXCreateNewContext(m_display, bestFbc, GLX_RGBA_TYPE, parameters.shared ? parameters.shareContext->m_impl->m_context : 0, True);
}
// If it does, try to get a GL 3.0 context!
else
{
int profile = parameters.compatibilityProfile ? GLX_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB : GLX_CONTEXT_CORE_PROFILE_BIT_ARB;
int debug = parameters.debugMode ? GLX_CONTEXT_DEBUG_BIT_ARB : 0;
int major = 3;//parameters.majorVersion;
int minor = 3;//parameters.minorVersion;
int context_attribs[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, major,
GLX_CONTEXT_MINOR_VERSION_ARB, minor,
GLX_CONTEXT_PROFILE_MASK_ARB, profile,
GLX_CONTEXT_FLAGS_ARB, debug,
None, None
};
m_context = glXCreateContextAttribs(
m_display,
bestFbc,
parameters.shared ? parameters.shareContext->m_impl->m_context : 0,
True,
context_attribs
);
}
// Sync to ensure any errors generated are processed.
XSync(m_display, False);
XSetErrorHandler(oldHandler);
if (ctxErrorOccurred || !m_context)
{
NazaraError("Failed to create context, check the version");
return false;
}
onExit.Reset();
return true;
}
void ContextImpl::Destroy()
{
// Destroy the context
if (m_context)
{
if (glXGetCurrentContext() == m_context)
glXMakeCurrent(m_display, None, nullptr);
glXDestroyContext(m_display, m_context);
m_context = nullptr;
}
// Destroy the window if we own it
if (m_ownsWindow && m_window)
{
XFreeColormap(m_display, m_colormap);
XDestroyWindow(m_display, m_window);
m_ownsWindow = false;
m_window = 0;
XFlush(m_display);
}
}
void ContextImpl::EnableVerticalSync(bool enabled)
{
if (glXSwapIntervalEXT)
glXSwapIntervalEXT(m_display, glXGetCurrentDrawable(), enabled ? 1 : 0);
else if (NzglXSwapIntervalMESA)
NzglXSwapIntervalMESA(enabled ? 1 : 0);
else if (glXSwapIntervalSGI)
glXSwapIntervalSGI(enabled ? 1 : 0);
else
NazaraError("Vertical sync not supported");
}
void ContextImpl::SwapBuffers()
{
if (m_window)
glXSwapBuffers(m_display, m_window);
}
bool ContextImpl::Desactivate()
{
return glXMakeCurrent(m_display, None, nullptr) == true;
}
}

View File

@@ -0,0 +1,42 @@
// Copyright (C) 2015 Jérôme Leclercq
// This file is part of the "Nazara Engine".
// For conditions of distribution and use, see copyright notice in Config.hpp
#pragma once
#ifndef NAZARA_CONTEXTIMPL_HPP
#define NAZARA_CONTEXTIMPL_HPP
#include <Nazara/Renderer/OpenGL.hpp>
namespace Nz
{
struct ContextParameters;
class ContextImpl
{
public:
ContextImpl();
~ContextImpl();
bool Activate() const;
bool Create(ContextParameters& parameters);
void Destroy();
void EnableVerticalSync(bool enabled);
void SwapBuffers();
static bool Desactivate();
private:
GLX::Colormap m_colormap;
GLX::GLXContext m_context;
GLX::Window m_window;
bool m_ownsWindow;
};
}
#endif // NAZARA_CONTEXTIMPL_HPP

View File

@@ -2,19 +2,21 @@
// 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/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Log.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/RenderStates.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <SDL2/SDL_video.h>
#include <Nazara/Renderer/Debug.hpp>
#if defined(NAZARA_PLATFORM_GLX)
#include <Nazara/Platform/X11/Display.hpp>
#endif // NAZARA_PLATFORM_GLX
#include <set>
#include <sstream>
#include <stdexcept>
#include <unordered_map>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
@@ -26,7 +28,15 @@ namespace Nz
OpenGLFunc LoadEntry(const char* name, bool launchException = true)
{
OpenGLFunc entry = reinterpret_cast<OpenGLFunc>(SDL_GL_GetProcAddress(name));
#if defined(NAZARA_PLATFORM_WINDOWS)
OpenGLFunc entry = reinterpret_cast<OpenGLFunc>(wglGetProcAddress(name));
if (!entry) // wglGetProcAddress ne fonctionne pas sur les fonctions OpenGL <= 1.1
entry = reinterpret_cast<OpenGLFunc>(GetProcAddress(openGLlibrary, name));
#elif defined(NAZARA_PLATFORM_GLX)
OpenGLFunc entry = reinterpret_cast<OpenGLFunc>(GLX::glXGetProcAddress(reinterpret_cast<const unsigned char*>(name)));
#else
#error OS not handled
#endif
if (!entry && launchException)
{
@@ -41,19 +51,20 @@ namespace Nz
bool LoadLibrary()
{
if (SDL_GL_LoadLibrary(nullptr) != 0)
{
NazaraError(SDL_GetError());
return false;
}
#ifdef NAZARA_PLATFORM_WINDOWS
openGLlibrary = ::LoadLibraryA("opengl32.dll");
return openGLlibrary != nullptr;
#else
return true;
#endif
}
void UnloadLibrary()
{
SDL_GL_UnloadLibrary();
#ifdef NAZARA_PLATFORM_WINDOWS
FreeLibrary(openGLlibrary);
#endif
}
enum GarbageResourceType
@@ -64,7 +75,7 @@ namespace Nz
struct ContextStates
{
std::vector<std::pair<GarbageResourceType, GLuint> > garbage; // Les ressources à supprimer dès que possible
std::vector<std::pair<GarbageResourceType, GLuint>> garbage; // Les ressources à supprimer dès que possible
GLuint buffersBinding[BufferType_Max + 1] = {0};
GLuint currentProgram = 0;
GLuint samplers[32] = {0}; // 32 est pour l'instant la plus haute limite (GL_TEXTURE31)
@@ -147,13 +158,15 @@ namespace Nz
// Les fonctions de blend n'a aucun intérêt sans blending
if (states.blending)
{
if (currentRenderStates.dstBlend != states.dstBlend ||
currentRenderStates.srcBlend != states.srcBlend)
currentRenderStates.srcBlend != states.srcBlend)
{
glBlendFunc(BlendFunc[states.srcBlend], BlendFunc[states.dstBlend]);
currentRenderStates.dstBlend = states.dstBlend;
currentRenderStates.srcBlend = states.srcBlend;
}
}
if (states.depthBuffer)
{
@@ -174,11 +187,13 @@ namespace Nz
// Inutile de changer le mode de face culling s'il n'est pas actif
if (states.faceCulling)
{
if (currentRenderStates.cullingSide != states.cullingSide)
{
glCullFace(FaceSide[states.cullingSide]);
currentRenderStates.cullingSide = states.cullingSide;
}
}
if (currentRenderStates.faceFilling != states.faceFilling)
{
@@ -190,8 +205,8 @@ namespace Nz
if (states.stencilTest)
{
if (currentRenderStates.stencilCompare.back != states.stencilCompare.back ||
currentRenderStates.stencilReference.back != states.stencilReference.back ||
currentRenderStates.stencilWriteMask.back != states.stencilWriteMask.back)
currentRenderStates.stencilReference.back != states.stencilReference.back ||
currentRenderStates.stencilWriteMask.back != states.stencilWriteMask.back)
{
glStencilFuncSeparate(GL_BACK, RendererComparison[states.stencilCompare.back], states.stencilReference.back, states.stencilWriteMask.back);
currentRenderStates.stencilCompare.back = states.stencilCompare.back;
@@ -200,8 +215,8 @@ namespace Nz
}
if (currentRenderStates.stencilDepthFail.back != states.stencilDepthFail.back ||
currentRenderStates.stencilFail.back != states.stencilFail.back ||
currentRenderStates.stencilPass.back != states.stencilPass.back)
currentRenderStates.stencilFail.back != states.stencilFail.back ||
currentRenderStates.stencilPass.back != states.stencilPass.back)
{
glStencilOpSeparate(GL_BACK, StencilOperation[states.stencilFail.back], StencilOperation[states.stencilDepthFail.back], StencilOperation[states.stencilPass.back]);
currentRenderStates.stencilDepthFail.back = states.stencilDepthFail.back;
@@ -210,8 +225,8 @@ namespace Nz
}
if (currentRenderStates.stencilCompare.front != states.stencilCompare.front ||
currentRenderStates.stencilReference.front != states.stencilReference.front ||
currentRenderStates.stencilWriteMask.front != states.stencilWriteMask.front)
currentRenderStates.stencilReference.front != states.stencilReference.front ||
currentRenderStates.stencilWriteMask.front != states.stencilWriteMask.front)
{
glStencilFuncSeparate(GL_FRONT, RendererComparison[states.stencilCompare.front], states.stencilReference.front, states.stencilWriteMask.front);
currentRenderStates.stencilCompare.front = states.stencilCompare.front;
@@ -220,8 +235,8 @@ namespace Nz
}
if (currentRenderStates.stencilDepthFail.front != states.stencilDepthFail.front ||
currentRenderStates.stencilFail.front != states.stencilFail.front ||
currentRenderStates.stencilPass.front != states.stencilPass.front)
currentRenderStates.stencilFail.front != states.stencilFail.front ||
currentRenderStates.stencilPass.front != states.stencilPass.front)
{
glStencilOpSeparate(GL_FRONT, StencilOperation[states.stencilFail.front], StencilOperation[states.stencilDepthFail.front], StencilOperation[states.stencilPass.front]);
currentRenderStates.stencilDepthFail.front = states.stencilDepthFail.front;
@@ -716,8 +731,14 @@ namespace Nz
if (s_initialized)
return true;
if (SDL_VideoInit(NULL) != 0)
NazaraError(SDL_GetError());
#if defined(NAZARA_PLATFORM_GLX)
Initializer<X11> display;
if (!display)
{
NazaraError("Failed to load display library");
return false;
}
#endif
if (!LoadLibrary())
{
@@ -737,15 +758,20 @@ namespace Nz
parameters.shared = false;
/*
Note: Même le contexte de chargement nécessite quelques fonctions de base pour correctement s'initialiser
Pour cette raison, deux contextes sont créés, le premier sert à récupérer les fonctions permetttant
de créer le second avec les bons paramètres.
Note: Même le contexte de chargement nécessite quelques fonctions de base pour correctement s'initialiser
Pour cette raison, deux contextes sont créés, le premier sert à récupérer les fonctions permetttant
de créer le second avec les bons paramètres.
Non sérieusement si vous avez une meilleure idée, contactez-moi
*/
Non sérieusement si vous avez une meilleure idée, contactez-moi
*/
/****************************Chargement OpenGL****************************/
///FIXME: I'm really thinking this is a mistake and GLX has no need to be initialized differently (Lynix)
#if defined(NAZARA_PLATFORM_LINUX)
glXCreateContextAttribs = reinterpret_cast<GLX::PFNGLXCREATECONTEXTATTRIBSARBPROC>(LoadEntry("glXCreateContextAttribsARB", false));
#endif
Context loadContext;
if (!loadContext.Create(parameters))
{
@@ -753,6 +779,13 @@ namespace Nz
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));
#endif
// Récupération de la version d'OpenGL et du GLSL
// 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 chez AMD, NVidia et Intel, mais j'aimerai une preuve que ça sera toujours le cas...
@@ -998,6 +1031,16 @@ namespace Nz
glInvalidateBufferData = reinterpret_cast<PFNGLINVALIDATEBUFFERDATAPROC>(LoadEntry("glInvalidateBufferData", false));
glVertexAttribLPointer = reinterpret_cast<PFNGLVERTEXATTRIBLPOINTERPROC>(LoadEntry("glVertexAttribLPointer", false));
#if defined(NAZARA_PLATFORM_WINDOWS)
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_GLX)
glXSwapIntervalEXT = reinterpret_cast<GLX::PFNGLXSWAPINTERVALEXTPROC>(LoadEntry("glXSwapIntervalEXT", false));
NzglXSwapIntervalMESA = reinterpret_cast<GLX::PFNGLXSWAPINTERVALMESAPROC>(LoadEntry("glXSwapIntervalMESA", false));
glXSwapIntervalSGI = reinterpret_cast<GLX::PFNGLXSWAPINTERVALSGIPROC>(LoadEntry("glXSwapIntervalSGI", false));
#endif
if (!glGetStringi || !LoadExtensions3())
{
NazaraWarning("Failed to load OpenGL 3 extension system, falling back to OpenGL 2 extension system...");
@@ -1006,6 +1049,21 @@ namespace Nz
NazaraWarning("Failed to load extension system");
}
#ifdef NAZARA_PLATFORM_WINDOWS
{
bool loaded;
if (wglGetExtensionsStringARB)
loaded = LoadExtensionsString(reinterpret_cast<const char*>(wglGetExtensionsStringARB(wglGetCurrentDC())));
else if (wglGetExtensionsStringEXT)
loaded = LoadExtensionsString(reinterpret_cast<const char*>(wglGetExtensionsStringEXT()));
else
loaded = false;
if (!loaded)
NazaraWarning("Failed to load wgl extension string");
}
#endif
// AnisotropicFilter
s_openGLextensions[OpenGLExtension_AnisotropicFilter] = IsSupported("GL_EXT_texture_filter_anisotropic");
@@ -1174,7 +1232,7 @@ namespace Nz
bool OpenGL::IsSupported(const String& string)
{
return SDL_GL_ExtensionSupported(string.GetConstBuffer());
return s_openGLextensionSet.find(string) != s_openGLextensionSet.end();
}
void OpenGL::SetBuffer(BufferType type, GLuint id)
@@ -1840,7 +1898,7 @@ namespace Nz
GLenum OpenGL::BufferTarget[] =
{
GL_ELEMENT_ARRAY_BUFFER, // BufferType_Index,
GL_ARRAY_BUFFER, // BufferType_Vertex
GL_ARRAY_BUFFER, // BufferType_Vertex
};
static_assert(BufferType_Max + 1 == 2, "Buffer target array is incomplete");
@@ -1848,7 +1906,7 @@ namespace Nz
GLenum OpenGL::BufferTargetBinding[] =
{
GL_ELEMENT_ARRAY_BUFFER_BINDING, // BufferType_Index,
GL_ARRAY_BUFFER_BINDING, // BufferType_Vertex
GL_ARRAY_BUFFER_BINDING, // BufferType_Vertex
};
static_assert(BufferType_Max + 1 == 2, "Buffer target binding array is incomplete");
@@ -1975,9 +2033,9 @@ namespace Nz
GLenum OpenGL::ShaderStage[] =
{
GL_FRAGMENT_SHADER, // ShaderStage_Fragment
GL_GEOMETRY_SHADER, // ShaderStage_Geometry
GL_VERTEX_SHADER // ShaderStage_Vertex
GL_FRAGMENT_SHADER, // ShaderStage_Fragment
GL_GEOMETRY_SHADER, // ShaderStage_Geometry
GL_VERTEX_SHADER // ShaderStage_Vertex
};
static_assert(ShaderStageType_Max + 1 == 3, "Shader stage array is incomplete");
@@ -2054,178 +2112,192 @@ namespace Nz
static_assert(VertexComponent_Max + 1 == 16, "Attribute index array is incomplete");
PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr;
PFNGLATTACHSHADERPROC glAttachShader = nullptr;
PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender = nullptr;
PFNGLBEGINQUERYPROC glBeginQuery = nullptr;
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = nullptr;
PFNGLBINDBUFFERPROC glBindBuffer = nullptr;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = nullptr;
PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation = nullptr;
PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = nullptr;
PFNGLBINDSAMPLERPROC glBindSampler = nullptr;
PFNGLBINDTEXTUREPROC glBindTexture = nullptr;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr;
PFNGLBLENDFUNCPROC glBlendFunc = nullptr;
PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = nullptr;
PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = nullptr;
PFNGLBUFFERDATAPROC glBufferData = nullptr;
PFNGLBUFFERSUBDATAPROC glBufferSubData = nullptr;
PFNGLCLEARPROC glClear = nullptr;
PFNGLCLEARCOLORPROC glClearColor = nullptr;
PFNGLCLEARDEPTHPROC glClearDepth = nullptr;
PFNGLCLEARSTENCILPROC glClearStencil = nullptr;
PFNGLCREATEPROGRAMPROC glCreateProgram = nullptr;
PFNGLCREATESHADERPROC glCreateShader = nullptr;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = nullptr;
PFNGLCOLORMASKPROC glColorMask = nullptr;
PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D = nullptr;
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D = nullptr;
PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D = nullptr;
PFNGLCULLFACEPROC glCullFace = nullptr;
PFNGLCOMPILESHADERPROC glCompileShader = nullptr;
PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D = nullptr;
PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback = nullptr;
PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl = nullptr;
PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert = nullptr;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = nullptr;
PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr;
PFNGLDELETEQUERIESPROC glDeleteQueries = nullptr;
PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = nullptr;
PFNGLDELETESAMPLERSPROC glDeleteSamplers = nullptr;
PFNGLDELETESHADERPROC glDeleteShader = nullptr;
PFNGLDELETETEXTURESPROC glDeleteTextures = nullptr;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = nullptr;
PFNGLDEPTHFUNCPROC glDepthFunc = nullptr;
PFNGLDEPTHMASKPROC glDepthMask = nullptr;
PFNGLDISABLEPROC glDisable = nullptr;
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = nullptr;
PFNGLDRAWARRAYSPROC glDrawArrays = nullptr;
PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced = nullptr;
PFNGLDRAWBUFFERPROC glDrawBuffer = nullptr;
PFNGLDRAWBUFFERSPROC glDrawBuffers = nullptr;
PFNGLDRAWELEMENTSPROC glDrawElements = nullptr;
PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced = nullptr;
PFNGLDRAWTEXTURENVPROC glDrawTexture = nullptr;
PFNGLENABLEPROC glEnable = nullptr;
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = nullptr;
PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender = nullptr;
PFNGLENDQUERYPROC glEndQuery = nullptr;
PFNGLFLUSHPROC glFlush = nullptr;
PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = nullptr;
PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture = nullptr;
PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D = nullptr;
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = nullptr;
PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D = nullptr;
PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = nullptr;
PFNGLGENERATEMIPMAPPROC glGenerateMipmap = nullptr;
PFNGLGENBUFFERSPROC glGenBuffers = nullptr;
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = nullptr;
PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = nullptr;
PFNGLGENQUERIESPROC glGenQueries = nullptr;
PFNGLGENSAMPLERSPROC glGenSamplers = nullptr;
PFNGLGENTEXTURESPROC glGenTextures = nullptr;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr;
PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform = nullptr;
PFNGLGETBOOLEANVPROC glGetBooleanv = nullptr;
PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr;
PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog = nullptr;
PFNGLGETERRORPROC glGetError = nullptr;
PFNGLGETFLOATVPROC glGetFloatv = nullptr;
PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
PFNGLGETPROGRAMBINARYPROC glGetProgramBinary = nullptr;
PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr;
PFNGLGETQUERYIVPROC glGetQueryiv = nullptr;
PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv = nullptr;
PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv = nullptr;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = nullptr;
PFNGLGETSHADERIVPROC glGetShaderiv = nullptr;
PFNGLGETSHADERSOURCEPROC glGetShaderSource = nullptr;
PFNGLGETSTRINGPROC glGetString = nullptr;
PFNGLGETSTRINGIPROC glGetStringi = nullptr;
PFNGLGETTEXIMAGEPROC glGetTexImage = nullptr;
PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv = nullptr;
PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv = nullptr;
PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv = nullptr;
PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv = nullptr;
PFNGLGETUNIFORMFVPROC glGetUniformfv = nullptr;
PFNGLGETUNIFORMIVPROC glGetUniformiv = nullptr;
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
PFNGLINVALIDATEBUFFERDATAPROC glInvalidateBufferData = nullptr;
PFNGLISENABLEDPROC glIsEnabled = nullptr;
PFNGLLINEWIDTHPROC glLineWidth = nullptr;
PFNGLLINKPROGRAMPROC glLinkProgram = nullptr;
PFNGLMAPBUFFERPROC glMapBuffer = nullptr;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr;
PFNGLPIXELSTOREIPROC glPixelStorei = nullptr;
PFNGLPOINTSIZEPROC glPointSize = nullptr;
PFNGLPOLYGONMODEPROC glPolygonMode = nullptr;
PFNGLPROGRAMBINARYPROC glProgramBinary = nullptr;
PFNGLPROGRAMPARAMETERIPROC glProgramParameteri = nullptr;
PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr;
PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr;
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = nullptr;
PFNGLPROGRAMUNIFORM1DVPROC glProgramUniform1dv = nullptr;
PFNGLPROGRAMUNIFORM1FVPROC glProgramUniform1fv = nullptr;
PFNGLPROGRAMUNIFORM1IVPROC glProgramUniform1iv = nullptr;
PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv = nullptr;
PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv = nullptr;
PFNGLPROGRAMUNIFORM2IVPROC glProgramUniform2iv = nullptr;
PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv = nullptr;
PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv = nullptr;
PFNGLPROGRAMUNIFORM3IVPROC glProgramUniform3iv = nullptr;
PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv = nullptr;
PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv = nullptr;
PFNGLPROGRAMUNIFORM4IVPROC glProgramUniform4iv = nullptr;
PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv = nullptr;
PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv = nullptr;
PFNGLREADPIXELSPROC glReadPixels = nullptr;
PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = nullptr;
PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf = nullptr;
PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri = nullptr;
PFNGLSCISSORPROC glScissor = nullptr;
PFNGLSHADERSOURCEPROC glShaderSource = nullptr;
PFNGLSTENCILFUNCPROC glStencilFunc = nullptr;
PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate = nullptr;
PFNGLSTENCILOPPROC glStencilOp = nullptr;
PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate = nullptr;
PFNGLTEXIMAGE1DPROC glTexImage1D = nullptr;
PFNGLTEXIMAGE2DPROC glTexImage2D = 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;
PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr;
PFNGLUNIFORM1DPROC glUniform1d = nullptr;
PFNGLUNIFORM1FPROC glUniform1f = nullptr;
PFNGLUNIFORM1IPROC glUniform1i = nullptr;
PFNGLUNIFORM1DVPROC glUniform1dv = nullptr;
PFNGLUNIFORM1FVPROC glUniform1fv = nullptr;
PFNGLUNIFORM1IVPROC glUniform1iv = nullptr;
PFNGLUNIFORM2DVPROC glUniform2dv = nullptr;
PFNGLUNIFORM2FVPROC glUniform2fv = nullptr;
PFNGLUNIFORM2IVPROC glUniform2iv = nullptr;
PFNGLUNIFORM3DVPROC glUniform3dv = nullptr;
PFNGLUNIFORM3FVPROC glUniform3fv = nullptr;
PFNGLUNIFORM3IVPROC glUniform3iv = nullptr;
PFNGLUNIFORM4DVPROC glUniform4dv = nullptr;
PFNGLUNIFORM4FVPROC glUniform4fv = nullptr;
PFNGLUNIFORM4IVPROC glUniform4iv = nullptr;
PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv = nullptr;
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = nullptr;
PFNGLUNMAPBUFFERPROC glUnmapBuffer = nullptr;
PFNGLUSEPROGRAMPROC glUseProgram = nullptr;
PFNGLVALIDATEPROGRAMPROC glValidateProgram = nullptr;
PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = nullptr;
PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor = nullptr;
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = nullptr;
PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = nullptr;
PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer = nullptr;
PFNGLVIEWPORTPROC glViewport = nullptr;
PFNGLACTIVETEXTUREPROC glActiveTexture = nullptr;
PFNGLATTACHSHADERPROC glAttachShader = nullptr;
PFNGLBEGINCONDITIONALRENDERPROC glBeginConditionalRender = nullptr;
PFNGLBEGINQUERYPROC glBeginQuery = nullptr;
PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation = nullptr;
PFNGLBINDBUFFERPROC glBindBuffer = nullptr;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer = nullptr;
PFNGLBINDFRAGDATALOCATIONPROC glBindFragDataLocation = nullptr;
PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer = nullptr;
PFNGLBINDSAMPLERPROC glBindSampler = nullptr;
PFNGLBINDTEXTUREPROC glBindTexture = nullptr;
PFNGLBINDVERTEXARRAYPROC glBindVertexArray = nullptr;
PFNGLBLENDFUNCPROC glBlendFunc = nullptr;
PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate = nullptr;
PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer = nullptr;
PFNGLBUFFERDATAPROC glBufferData = nullptr;
PFNGLBUFFERSUBDATAPROC glBufferSubData = nullptr;
PFNGLCLEARPROC glClear = nullptr;
PFNGLCLEARCOLORPROC glClearColor = nullptr;
PFNGLCLEARDEPTHPROC glClearDepth = nullptr;
PFNGLCLEARSTENCILPROC glClearStencil = nullptr;
PFNGLCREATEPROGRAMPROC glCreateProgram = nullptr;
PFNGLCREATESHADERPROC glCreateShader = nullptr;
PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus = nullptr;
PFNGLCOLORMASKPROC glColorMask = nullptr;
PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glCompressedTexSubImage1D = nullptr;
PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D = nullptr;
PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glCompressedTexSubImage3D = nullptr;
PFNGLCULLFACEPROC glCullFace = nullptr;
PFNGLCOMPILESHADERPROC glCompileShader = nullptr;
PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D = nullptr;
PFNGLDEBUGMESSAGECALLBACKPROC glDebugMessageCallback = nullptr;
PFNGLDEBUGMESSAGECONTROLPROC glDebugMessageControl = nullptr;
PFNGLDEBUGMESSAGEINSERTPROC glDebugMessageInsert = nullptr;
PFNGLDELETEBUFFERSPROC glDeleteBuffers = nullptr;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers = nullptr;
PFNGLDELETEPROGRAMPROC glDeleteProgram = nullptr;
PFNGLDELETEQUERIESPROC glDeleteQueries = nullptr;
PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers = nullptr;
PFNGLDELETESAMPLERSPROC glDeleteSamplers = nullptr;
PFNGLDELETESHADERPROC glDeleteShader = nullptr;
PFNGLDELETETEXTURESPROC glDeleteTextures = nullptr;
PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays = nullptr;
PFNGLDEPTHFUNCPROC glDepthFunc = nullptr;
PFNGLDEPTHMASKPROC glDepthMask = nullptr;
PFNGLDISABLEPROC glDisable = nullptr;
PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray = nullptr;
PFNGLDRAWARRAYSPROC glDrawArrays = nullptr;
PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced = nullptr;
PFNGLDRAWBUFFERPROC glDrawBuffer = nullptr;
PFNGLDRAWBUFFERSPROC glDrawBuffers = nullptr;
PFNGLDRAWELEMENTSPROC glDrawElements = nullptr;
PFNGLDRAWELEMENTSINSTANCEDPROC glDrawElementsInstanced = nullptr;
PFNGLDRAWTEXTURENVPROC glDrawTexture = nullptr;
PFNGLENABLEPROC glEnable = nullptr;
PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray = nullptr;
PFNGLENDCONDITIONALRENDERPROC glEndConditionalRender = nullptr;
PFNGLENDQUERYPROC glEndQuery = nullptr;
PFNGLFLUSHPROC glFlush = nullptr;
PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer = nullptr;
PFNGLFRAMEBUFFERTEXTUREPROC glFramebufferTexture = nullptr;
PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D = nullptr;
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D = nullptr;
PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D = nullptr;
PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer = nullptr;
PFNGLGENERATEMIPMAPPROC glGenerateMipmap = nullptr;
PFNGLGENBUFFERSPROC glGenBuffers = nullptr;
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers = nullptr;
PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers = nullptr;
PFNGLGENQUERIESPROC glGenQueries = nullptr;
PFNGLGENSAMPLERSPROC glGenSamplers = nullptr;
PFNGLGENTEXTURESPROC glGenTextures = nullptr;
PFNGLGENVERTEXARRAYSPROC glGenVertexArrays = nullptr;
PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform = nullptr;
PFNGLGETBOOLEANVPROC glGetBooleanv = nullptr;
PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv = nullptr;
PFNGLGETDEBUGMESSAGELOGPROC glGetDebugMessageLog = nullptr;
PFNGLGETERRORPROC glGetError = nullptr;
PFNGLGETFLOATVPROC glGetFloatv = nullptr;
PFNGLGETINTEGERVPROC glGetIntegerv = nullptr;
PFNGLGETPROGRAMBINARYPROC glGetProgramBinary = nullptr;
PFNGLGETPROGRAMIVPROC glGetProgramiv = nullptr;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog = nullptr;
PFNGLGETQUERYIVPROC glGetQueryiv = nullptr;
PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv = nullptr;
PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv = nullptr;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog = nullptr;
PFNGLGETSHADERIVPROC glGetShaderiv = nullptr;
PFNGLGETSHADERSOURCEPROC glGetShaderSource = nullptr;
PFNGLGETSTRINGPROC glGetString = nullptr;
PFNGLGETSTRINGIPROC glGetStringi = nullptr;
PFNGLGETTEXIMAGEPROC glGetTexImage = nullptr;
PFNGLGETTEXLEVELPARAMETERFVPROC glGetTexLevelParameterfv = nullptr;
PFNGLGETTEXLEVELPARAMETERIVPROC glGetTexLevelParameteriv = nullptr;
PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv = nullptr;
PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv = nullptr;
PFNGLGETUNIFORMFVPROC glGetUniformfv = nullptr;
PFNGLGETUNIFORMIVPROC glGetUniformiv = nullptr;
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation = nullptr;
PFNGLINVALIDATEBUFFERDATAPROC glInvalidateBufferData = nullptr;
PFNGLISENABLEDPROC glIsEnabled = nullptr;
PFNGLLINEWIDTHPROC glLineWidth = nullptr;
PFNGLLINKPROGRAMPROC glLinkProgram = nullptr;
PFNGLMAPBUFFERPROC glMapBuffer = nullptr;
PFNGLMAPBUFFERRANGEPROC glMapBufferRange = nullptr;
PFNGLPIXELSTOREIPROC glPixelStorei = nullptr;
PFNGLPOINTSIZEPROC glPointSize = nullptr;
PFNGLPOLYGONMODEPROC glPolygonMode = nullptr;
PFNGLPROGRAMBINARYPROC glProgramBinary = nullptr;
PFNGLPROGRAMPARAMETERIPROC glProgramParameteri = nullptr;
PFNGLPROGRAMUNIFORM1DPROC glProgramUniform1d = nullptr;
PFNGLPROGRAMUNIFORM1FPROC glProgramUniform1f = nullptr;
PFNGLPROGRAMUNIFORM1IPROC glProgramUniform1i = nullptr;
PFNGLPROGRAMUNIFORM1DVPROC glProgramUniform1dv = nullptr;
PFNGLPROGRAMUNIFORM1FVPROC glProgramUniform1fv = nullptr;
PFNGLPROGRAMUNIFORM1IVPROC glProgramUniform1iv = nullptr;
PFNGLPROGRAMUNIFORM2DVPROC glProgramUniform2dv = nullptr;
PFNGLPROGRAMUNIFORM2FVPROC glProgramUniform2fv = nullptr;
PFNGLPROGRAMUNIFORM2IVPROC glProgramUniform2iv = nullptr;
PFNGLPROGRAMUNIFORM3DVPROC glProgramUniform3dv = nullptr;
PFNGLPROGRAMUNIFORM3FVPROC glProgramUniform3fv = nullptr;
PFNGLPROGRAMUNIFORM3IVPROC glProgramUniform3iv = nullptr;
PFNGLPROGRAMUNIFORM4DVPROC glProgramUniform4dv = nullptr;
PFNGLPROGRAMUNIFORM4FVPROC glProgramUniform4fv = nullptr;
PFNGLPROGRAMUNIFORM4IVPROC glProgramUniform4iv = nullptr;
PFNGLPROGRAMUNIFORMMATRIX4DVPROC glProgramUniformMatrix4dv = nullptr;
PFNGLPROGRAMUNIFORMMATRIX4FVPROC glProgramUniformMatrix4fv = nullptr;
PFNGLREADPIXELSPROC glReadPixels = nullptr;
PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage = nullptr;
PFNGLSAMPLERPARAMETERFPROC glSamplerParameterf = nullptr;
PFNGLSAMPLERPARAMETERIPROC glSamplerParameteri = nullptr;
PFNGLSCISSORPROC glScissor = nullptr;
PFNGLSHADERSOURCEPROC glShaderSource = nullptr;
PFNGLSTENCILFUNCPROC glStencilFunc = nullptr;
PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate = nullptr;
PFNGLSTENCILOPPROC glStencilOp = nullptr;
PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate = nullptr;
PFNGLTEXIMAGE1DPROC glTexImage1D = nullptr;
PFNGLTEXIMAGE2DPROC glTexImage2D = 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;
PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D = nullptr;
PFNGLUNIFORM1DPROC glUniform1d = nullptr;
PFNGLUNIFORM1FPROC glUniform1f = nullptr;
PFNGLUNIFORM1IPROC glUniform1i = nullptr;
PFNGLUNIFORM1DVPROC glUniform1dv = nullptr;
PFNGLUNIFORM1FVPROC glUniform1fv = nullptr;
PFNGLUNIFORM1IVPROC glUniform1iv = nullptr;
PFNGLUNIFORM2DVPROC glUniform2dv = nullptr;
PFNGLUNIFORM2FVPROC glUniform2fv = nullptr;
PFNGLUNIFORM2IVPROC glUniform2iv = nullptr;
PFNGLUNIFORM3DVPROC glUniform3dv = nullptr;
PFNGLUNIFORM3FVPROC glUniform3fv = nullptr;
PFNGLUNIFORM3IVPROC glUniform3iv = nullptr;
PFNGLUNIFORM4DVPROC glUniform4dv = nullptr;
PFNGLUNIFORM4FVPROC glUniform4fv = nullptr;
PFNGLUNIFORM4IVPROC glUniform4iv = nullptr;
PFNGLUNIFORMMATRIX4DVPROC glUniformMatrix4dv = nullptr;
PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv = nullptr;
PFNGLUNMAPBUFFERPROC glUnmapBuffer = nullptr;
PFNGLUSEPROGRAMPROC glUseProgram = nullptr;
PFNGLVALIDATEPROGRAMPROC glValidateProgram = nullptr;
PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f = nullptr;
PFNGLVERTEXATTRIBDIVISORPROC glVertexAttribDivisor = nullptr;
PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer = nullptr;
PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer = nullptr;
PFNGLVERTEXATTRIBLPOINTERPROC glVertexAttribLPointer = nullptr;
PFNGLVIEWPORTPROC glViewport = nullptr;
#if defined(NAZARA_PLATFORM_WINDOWS)
PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormat = nullptr;
PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = nullptr;
PFNWGLGETEXTENSIONSSTRINGARBPROC wglGetExtensionsStringARB = nullptr;
PFNWGLGETEXTENSIONSSTRINGEXTPROC wglGetExtensionsStringEXT = nullptr;
PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = nullptr;
#elif defined(NAZARA_PLATFORM_GLX)
GLX::PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = nullptr;
GLX::PFNGLXSWAPINTERVALEXTPROC glXSwapIntervalEXT = nullptr;
GLX::PFNGLXSWAPINTERVALMESAPROC NzglXSwapIntervalMESA = nullptr;
GLX::PFNGLXSWAPINTERVALSGIPROC glXSwapIntervalSGI = nullptr;
#endif
}

View File

@@ -234,7 +234,7 @@ namespace Nz
bool RenderWindow::OnWindowCreated()
{
m_parameters.doubleBuffered = true;
m_parameters.window = GetHandle();
m_parameters.window = GetSystemHandle();
std::unique_ptr<Context> context(new Context);
if (!context->Create(m_parameters))

View File

@@ -1,147 +0,0 @@
// Copyright (C) 2017 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/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/Debug.hpp>
#include <Nazara/Renderer/OpenGL.hpp>
#include <Nazara/Renderer/SDL2/ContextImpl.hpp>
#include <array>
#include <cstring>
namespace Nz
{
ContextImpl::ContextImpl()
{
}
bool ContextImpl::Activate() const
{
bool success = SDL_GL_MakeCurrent(m_window, m_context) == 0;
if (!success)
NazaraError(SDL_GetError());
else
lastActive = m_window;
return success;
}
bool ContextImpl::Create(ContextParameters& parameters)
{
if (parameters.window)
{
m_window = static_cast<SDL_Window*>(parameters.window);
m_ownsWindow = false;
}
else
{
m_window = SDL_CreateWindow("STATIC", 0, 0, 1, 1, SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN);
if (!m_window)
{
NazaraError("Failed to create window");
return false;
}
//SDL_HideWindow(m_window);
m_ownsWindow = true;
}
// En cas d'exception, la ressource sera quand même libérée
CallOnExit onExit([this] ()
{
Destroy();
});
bool valid = true;
std::array<std::pair<SDL_GLattr, int>, 13> attributes{
std::pair<SDL_GLattr, int>
{SDL_GL_CONTEXT_PROFILE_MASK, parameters.compatibilityProfile ? SDL_GL_CONTEXT_PROFILE_COMPATIBILITY : SDL_GL_CONTEXT_PROFILE_CORE},
{SDL_GL_CONTEXT_MAJOR_VERSION, parameters.majorVersion},
{SDL_GL_CONTEXT_MINOR_VERSION, parameters.minorVersion},
{SDL_GL_CONTEXT_FLAGS, parameters.debugMode ? SDL_GL_CONTEXT_DEBUG_FLAG : 0},
{SDL_GL_SHARE_WITH_CURRENT_CONTEXT, true},
{SDL_GL_RED_SIZE, (parameters.bitsPerPixel == 32) ? 8 : parameters.bitsPerPixel / 3}, // sad but I don't have a solution for now
{SDL_GL_GREEN_SIZE, (parameters.bitsPerPixel == 32) ? 8 : parameters.bitsPerPixel / 3},
{SDL_GL_BLUE_SIZE, (parameters.bitsPerPixel == 32) ? 8 : parameters.bitsPerPixel / 3},
{SDL_GL_ALPHA_SIZE, (parameters.bitsPerPixel == 32) ? 8 : 0},
{SDL_GL_DEPTH_SIZE, parameters.depthBits},
{SDL_GL_STENCIL_SIZE, parameters.stencilBits},
//{SDL_GL_DOUBLEBUFFER, parameters.doubleBuffered}, // doesn't work if we dont close all windows
{SDL_GL_MULTISAMPLEBUFFERS, parameters.antialiasingLevel > 0 ? GL_TRUE : GL_FALSE},
{SDL_GL_MULTISAMPLESAMPLES, parameters.antialiasingLevel}
};
for (const auto& attribute : attributes) {
valid &= SDL_GL_SetAttribute(attribute.first, attribute.second) == 0;
if (!valid) {
NazaraWarning(SDL_GetError());
break;
}
}
if (!valid)
NazaraWarning("Could not find a format matching requirements, disabling antialiasing...");
int antialiasingLevel;
SDL_GL_GetAttribute(SDL_GL_MULTISAMPLESAMPLES, &antialiasingLevel);
parameters.antialiasingLevel = static_cast<decltype(antialiasingLevel)>(antialiasingLevel);
onExit.Reset();
m_context = SDL_GL_CreateContext(m_window);
if (!m_context) {
NazaraError(SDL_GetError());
return false;
}
return true;
}
void ContextImpl::Destroy()
{
if (m_context)
{
SDL_GL_DeleteContext(m_context);
m_context = nullptr;
}
if (m_ownsWindow)
{
SDL_DestroyWindow(m_window);
m_window = nullptr;
}
}
void ContextImpl::EnableVerticalSync(bool enabled)
{
if (SDL_GL_SetSwapInterval(enabled ? 1 : 0) != 0)
NazaraError("Vertical sync not supported");
}
void ContextImpl::SwapBuffers()
{
SDL_GL_SwapWindow(m_window);
}
bool ContextImpl::Desactivate()
{
return SDL_GL_MakeCurrent(nullptr, nullptr) == 0;
}
SDL_Window* ContextImpl::lastActive = nullptr;
}

View File

@@ -0,0 +1,248 @@
// Copyright (C) 2017 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/Win32/ContextImpl.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/LockGuard.hpp>
#include <Nazara/Core/Mutex.hpp>
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/OpenGL.hpp>
#include <cstring>
#include <Nazara/Renderer/Debug.hpp>
namespace Nz
{
ContextImpl::ContextImpl() = default;
bool ContextImpl::Activate() const
{
return wglMakeCurrent(m_deviceContext, m_context) == TRUE;
}
bool ContextImpl::Create(ContextParameters& parameters)
{
if (parameters.window.type != WindowManager::None)
{
NazaraAssert(parameters.window.type == WindowManager::Windows, "Cannot create a context for a non-win32 window");
m_window = static_cast<HWND>(parameters.window.windows.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;
}
// En cas d'exception, la ressource sera quand même libérée
CallOnExit onExit([this] ()
{
Destroy();
});
m_deviceContext = GetDC(m_window);
if (!m_deviceContext)
{
NazaraError("Failed to get device context");
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) == TRUE);
}
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");
return false;
}
}
if (!SetPixelFormat(m_deviceContext, pixelFormat, &descriptor))
{
NazaraError("Failed to set pixel format");
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<ContextImpl*>(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;
// 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
}
if (parameters.debugMode)
{
*attrib++ = WGL_CONTEXT_FLAGS_ARB;
*attrib++ = WGL_CONTEXT_DEBUG_BIT_ARB;
}
*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 Mutex mutex;
LockGuard lock(mutex);
if (!wglShareLists(shareContext, m_context))
NazaraWarning("Failed to share the context: " + Error::GetLastSystemError());
}
}
if (!m_context)
{
NazaraError("Failed to create context");
return false;
}
onExit.Reset();
return true;
}
void ContextImpl::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 ContextImpl::EnableVerticalSync(bool enabled)
{
if (wglSwapInterval)
wglSwapInterval(enabled ? 1 : 0);
else
NazaraError("Vertical sync not supported");
}
void ContextImpl::SwapBuffers()
{
::SwapBuffers(m_deviceContext);
}
bool ContextImpl::Desactivate()
{
return wglMakeCurrent(nullptr, nullptr) == TRUE;
}
}

View File

@@ -9,7 +9,7 @@
#include <Nazara/Prerequisites.hpp>
#include <Nazara/Renderer/ContextParameters.hpp>
#include <SDL2/SDL.h>
#include <windows.h>
namespace Nz
{
@@ -31,11 +31,10 @@ namespace Nz
static bool Desactivate();
private:
SDL_GLContext m_context;
SDL_Window* m_window;
HDC m_deviceContext;
HGLRC m_context;
HWND m_window;
bool m_ownsWindow;
static SDL_Window* lastActive;
};
}