source/Platform/Unix/GLXContext: Initial implementation
This commit is contained in:
parent
b65cb9c2d2
commit
7dedabba57
2 changed files with 181 additions and 9 deletions
|
|
@ -1,51 +1,211 @@
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <Platform/PlatformDisplay.h>
|
||||||
|
#include <Spectre/System/Log.h>
|
||||||
|
|
||||||
|
#include "glad_glx.h"
|
||||||
|
#include "X11SharedDisplay.h"
|
||||||
#include "GLXContext.h"
|
#include "GLXContext.h"
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
||||||
GLXContext::GLXContext()
|
static bool loadGL() {
|
||||||
{
|
|
||||||
|
|
||||||
|
static bool init = false;
|
||||||
|
if (!init) {
|
||||||
|
int ver;
|
||||||
|
init = true;
|
||||||
|
|
||||||
|
ver = gladLoaderLoadGL();
|
||||||
|
if (!ver) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("GLX: Opengl Version %d.%d loaded.",
|
||||||
|
GLAD_VERSION_MAJOR(ver), GLAD_VERSION_MINOR(ver));
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that OpenGL extensions are loaded.
|
||||||
|
static bool ensureExtensionsLoaded(::Display* disp, int screen)
|
||||||
|
{
|
||||||
|
char msg[1024];
|
||||||
|
static bool init = false;
|
||||||
|
|
||||||
|
if (!init) {
|
||||||
|
int ver;
|
||||||
|
init = true;
|
||||||
|
|
||||||
|
ver = gladLoaderLoadGLX(disp, screen);
|
||||||
|
if (!ver) {
|
||||||
|
Log::warn("GLX: Could not load GLX extensions");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(msg, 1024, "GLX: GLX Version %d.%d loaded",
|
||||||
|
GLAD_VERSION_MAJOR(ver), GLAD_VERSION_MINOR(ver));
|
||||||
|
|
||||||
|
// Check for atleast version 1.4
|
||||||
|
if (ver < 10004) {
|
||||||
|
Log::error("%s but atleast version 1.4 is needed.", msg);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Log::info("%s.", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
GLXContext::GLXContext() :
|
||||||
|
m_disp (NULL),
|
||||||
|
m_win (0),
|
||||||
|
m_ctx (NULL)
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
GLXContext::~GLXContext()
|
GLXContext::~GLXContext()
|
||||||
{
|
{
|
||||||
|
destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLXContext::create(const PlatformDisplay* display)
|
bool GLXContext::create(const PlatformDisplay* display)
|
||||||
{
|
{
|
||||||
|
// Destroy any previous context first.
|
||||||
|
destroy();
|
||||||
|
|
||||||
|
m_disp = XGetDisplay();
|
||||||
|
if (m_disp == NULL) {
|
||||||
|
destroy();
|
||||||
|
Log::warn("X11: Could not open display");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_win = (::Window) display->getHandle();
|
||||||
|
|
||||||
|
if (!createGLContext()) {
|
||||||
|
destroy();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GLXContext::createGLContext()
|
||||||
|
{
|
||||||
|
::GLXFBConfig *fbc;
|
||||||
|
::XVisualInfo *info;
|
||||||
|
int fbcount;
|
||||||
|
|
||||||
|
GLint vi_attr[] = {
|
||||||
|
GLX_RGBA,
|
||||||
|
GLX_DEPTH_SIZE, 24,
|
||||||
|
GLX_DOUBLEBUFFER, 1,
|
||||||
|
GLX_RED_SIZE, 1,
|
||||||
|
GLX_GREEN_SIZE, 1,
|
||||||
|
GLX_BLUE_SIZE, 1,
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
GLint ctx_attr[] = {
|
||||||
|
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||||
|
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
|
||||||
|
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ensure glx extensions are loaded.
|
||||||
|
if (!ensureExtensionsLoaded(m_disp, DefaultScreen(m_disp))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
info = ::glXChooseVisual(m_disp, DefaultScreen(m_disp), vi_attr);
|
||||||
|
if (info == NULL) {
|
||||||
|
Log::warn("GLX: Could not find a valid VisualInfo.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup GL settings.
|
||||||
|
fbc = glXChooseFBConfig(m_disp, DefaultScreen(m_disp), (const int*) info->visual, &fbcount);
|
||||||
|
if (fbc == NULL) {
|
||||||
|
Log::warn("GLX: Could not find FB Config.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create context.
|
||||||
|
m_ctx = glXCreateContextAttribsARB(m_disp, fbc[0], NULL, GL_TRUE, ctx_attr);
|
||||||
|
if (m_ctx == NULL) {
|
||||||
|
Log::warn("GLX: Failed to create context.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
glXMakeCurrent(m_disp, m_win, m_ctx);
|
||||||
|
|
||||||
|
// Load OpenGL
|
||||||
|
if (!loadGL()) {
|
||||||
|
Log::warn("GLX: Could not load OpenGL");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLXContext::destroy()
|
void GLXContext::destroy()
|
||||||
{
|
{
|
||||||
|
if (m_ctx) {
|
||||||
|
::glXDestroyContext(m_disp, m_ctx);
|
||||||
|
m_ctx = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_disp) {
|
||||||
|
XReleaseDisplay();
|
||||||
|
m_disp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_win = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLXContext::activate()
|
bool GLXContext::activate()
|
||||||
{
|
{
|
||||||
return true;
|
if (m_win && m_ctx) {
|
||||||
|
return ::glXMakeCurrent(m_disp, m_win, m_ctx);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLXContext::deactivate()
|
bool GLXContext::deactivate()
|
||||||
{
|
{
|
||||||
return true;
|
return ::glXMakeCurrent(m_disp, None, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLXContext::isActive() const
|
bool GLXContext::isActive() const
|
||||||
{
|
{
|
||||||
return true;
|
return ::glXGetCurrentContext() == m_ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLXContext::setSwapInterval(int interval)
|
bool GLXContext::setSwapInterval(int interval)
|
||||||
{
|
{
|
||||||
return true;
|
ensureExtensionsLoaded(m_disp, DefaultScreen(m_disp));
|
||||||
|
|
||||||
|
if (GLAD_GLX_MESA_swap_control) {
|
||||||
|
return glXSwapIntervalMESA(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (GLAD_GLX_SGI_swap_control) {
|
||||||
|
return glXSwapIntervalSGI(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLXContext::setSize(unsigned int width, unsigned int height)
|
void GLXContext::setSize(unsigned int width, unsigned int height)
|
||||||
{
|
{
|
||||||
|
// TODO: Not GLX specific! move to generic GLContext class.
|
||||||
|
if (activate()) {
|
||||||
|
glViewport(0, 0, width, height);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLXContext::setSize(const Vector2u size)
|
void GLXContext::setSize(const Vector2u size)
|
||||||
|
|
@ -55,7 +215,7 @@ void GLXContext::setSize(const Vector2u size)
|
||||||
|
|
||||||
void GLXContext::swapBuffers()
|
void GLXContext::swapBuffers()
|
||||||
{
|
{
|
||||||
|
glXSwapBuffers(m_disp, m_win);
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
// X11 OpenGL Context (glx)
|
// X11 OpenGL Context (glx)
|
||||||
|
|
||||||
|
#include "glad_glx.h"
|
||||||
#include <Spectre/Display/GLContext.h>
|
#include <Spectre/Display/GLContext.h>
|
||||||
|
|
||||||
namespace sp {
|
namespace sp {
|
||||||
|
|
@ -32,6 +33,17 @@ public :
|
||||||
void setSize(const Vector2u size);
|
void setSize(const Vector2u size);
|
||||||
|
|
||||||
void swapBuffers();
|
void swapBuffers();
|
||||||
|
|
||||||
|
private :
|
||||||
|
bool createGLContext();
|
||||||
|
|
||||||
|
private :
|
||||||
|
|
||||||
|
::Display* m_disp;
|
||||||
|
|
||||||
|
::Window m_win;
|
||||||
|
|
||||||
|
::GLXContext m_ctx;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sp
|
} // namespace sp
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue