commit
a89a8151d5
|
@ -91,7 +91,7 @@ WX_CONFIG_CHECK(
|
|||
is in LD_LIBRARY_PATH or equivalent variable and
|
||||
wxWidgets version is $wxVersion or above.
|
||||
]) ],
|
||||
[core], )
|
||||
[core], [--version=2.9])
|
||||
|
||||
CPPFLAGS="$CPPFLAGS $WX_CPPFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $WX_CXXFLAGS_ONLY"
|
||||
|
|
|
@ -97,11 +97,6 @@ static NSOpenGLContext *gl_context_create(struct gs_init_data *info)
|
|||
return context;
|
||||
}
|
||||
|
||||
static inline void required_extension_error(const char *extension)
|
||||
{
|
||||
blog(LOG_ERROR, "OpenGL extension %s is required", extension);
|
||||
}
|
||||
|
||||
static bool gl_init_extensions(device_t device)
|
||||
{
|
||||
glewExperimental=true;
|
||||
|
@ -112,27 +107,6 @@ static bool gl_init_extensions(device_t device)
|
|||
return false;
|
||||
}
|
||||
|
||||
if(!GLEW_VERSION_2_1) {
|
||||
blog(LOG_ERROR, "OpenGL 2.1 minimum required by the graphics "
|
||||
"adapter");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!GLEW_ARB_framebuffer_object) {
|
||||
required_extension_error("GL_ARB_framebuffer_object");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!GLEW_ARB_separate_shader_objects) {
|
||||
required_extension_error("GL_ARB_separate_shader_objects");
|
||||
return false;
|
||||
}
|
||||
|
||||
//something inside glew produces error code 1280 (invalid enum)
|
||||
glGetError();
|
||||
|
||||
device->copy_type = COPY_TYPE_FBO_BLIT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,107 @@
|
|||
#include <graphics/matrix3.h>
|
||||
#include "gl-subsystem.h"
|
||||
|
||||
#ifdef _DEBUG
|
||||
/* Tables for OpenGL debug */
|
||||
static const char* debug_source_table[] = {
|
||||
"API",
|
||||
"Window System",
|
||||
"Shader Compiler",
|
||||
"Third Party"
|
||||
"Application",
|
||||
"Other"
|
||||
};
|
||||
|
||||
static const char* debug_type_table[] = {
|
||||
"Error",
|
||||
"Deprecated Behavior",
|
||||
"Undefined Behavior",
|
||||
"Portability",
|
||||
"Performance",
|
||||
"Other"
|
||||
};
|
||||
|
||||
static const char* debug_severity_table[] = {
|
||||
"High",
|
||||
"Medium",
|
||||
"Low"
|
||||
};
|
||||
|
||||
/* ARB and core values are the same. They'll always be linear so no hardcoding. */
|
||||
/* The values subtracted are the lowest value in the list of valid values. */
|
||||
#define GL_DEBUG_SOURCE_OFFSET(x) (x - GL_DEBUG_SOURCE_API_ARB)
|
||||
#define GL_DEBUG_TYPE_OFFSET(x) (x - GL_DEBUG_TYPE_ERROR_ARB)
|
||||
#define GL_DEBUG_SEVERITY_OFFSET(x) (x - GL_DEBUG_SEVERITY_HIGH_ARB)
|
||||
|
||||
static APIENTRY void gl_debug_proc(
|
||||
GLenum source, GLenum type, GLuint id, GLenum severity,
|
||||
GLsizei length, const GLchar *message, GLvoid *data )
|
||||
{
|
||||
blog( LOG_DEBUG,
|
||||
"[%s][%s]{%s}: %.*s",
|
||||
debug_source_table[GL_DEBUG_SOURCE_OFFSET(source)],
|
||||
debug_type_table[GL_DEBUG_TYPE_OFFSET(type)],
|
||||
debug_severity_table[GL_DEBUG_SEVERITY_OFFSET(severity)],
|
||||
length, message
|
||||
);
|
||||
}
|
||||
|
||||
static void gl_enable_debug()
|
||||
{
|
||||
/* Perhaps we should create GLEW contexts? */
|
||||
|
||||
if (GLEW_VERSION_4_0)
|
||||
glDebugMessageCallback(gl_debug_proc, NULL);
|
||||
else if (GLEW_ARB_debug_output)
|
||||
glDebugMessageCallbackARB(gl_debug_proc, NULL);
|
||||
else {
|
||||
blog(LOG_DEBUG, "Failed to set GL debug callback as it is not supported.");
|
||||
return;
|
||||
}
|
||||
|
||||
gl_enable(GL_DEBUG_OUTPUT);
|
||||
}
|
||||
#else
|
||||
static void gl_enable_debug() {}
|
||||
#endif
|
||||
|
||||
static inline void required_extension_error(const char *extension)
|
||||
{
|
||||
}
|
||||
|
||||
static bool gl_init_extensions(struct gs_device* device)
|
||||
{
|
||||
if (!GLEW_VERSION_2_1) {
|
||||
blog(LOG_ERROR, "obs-studio requires OpenGL version 2.1 or higher.");
|
||||
return false;
|
||||
}
|
||||
|
||||
gl_enable_debug();
|
||||
|
||||
if (!GLEW_VERSION_3_0 && !GLEW_ARB_framebuffer_object) {
|
||||
blog(LOG_ERROR, "OpenGL extension ARB_framebuffer_object is required.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GLEW_VERSION_3_1 || GLEW_ARB_seamless_cube_map) {
|
||||
gl_enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
}
|
||||
|
||||
if (!GLEW_VERSION_4_1 && !GLEW_ARB_separate_shader_objects) {
|
||||
blog(LOG_ERROR, "OpenGL extension ARB_separate_shader_objects is required.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GLEW_ARB_copy_image || GLEW_VERSION_4_2)
|
||||
device->copy_type = COPY_TYPE_ARB;
|
||||
else if (GLEW_NV_copy_image)
|
||||
device->copy_type = COPY_TYPE_NV;
|
||||
else
|
||||
device->copy_type = COPY_TYPE_FBO_BLIT; /* ?? */
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void clear_textures(struct gs_device *device)
|
||||
{
|
||||
GLenum i;
|
||||
|
@ -69,6 +170,11 @@ device_t device_create(struct gs_init_data *info)
|
|||
if (!device->plat)
|
||||
goto fail;
|
||||
|
||||
if (!gl_init_extensions(device))
|
||||
goto fail;
|
||||
|
||||
gl_enable(GL_CULL_FACE);
|
||||
|
||||
glGenProgramPipelines(1, &device->pipeline);
|
||||
if (!gl_success("glGenProgramPipelines"))
|
||||
goto fail;
|
||||
|
@ -77,14 +183,6 @@ device_t device_create(struct gs_init_data *info)
|
|||
if (!gl_success("glBindProgramPipeline"))
|
||||
goto fail;
|
||||
|
||||
#ifdef _DEBUG
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
if (glGetError() == GL_INVALID_ENUM)
|
||||
blog(LOG_DEBUG, "OpenGL debug information not available");
|
||||
#endif
|
||||
|
||||
gl_enable(GL_CULL_FACE);
|
||||
|
||||
device_leavecontext(device);
|
||||
device->cur_swap = gl_platform_getswap(device->plat);
|
||||
|
||||
|
@ -1045,7 +1143,7 @@ void device_frustum(device_t device, float left, float right,
|
|||
|
||||
dst->x.x = nearx2 / rml;
|
||||
dst->z.x = (left+right) / rml;
|
||||
|
||||
|
||||
dst->y.y = nearx2 / tmb;
|
||||
dst->z.y = (bottom+top) / tmb;
|
||||
|
||||
|
|
|
@ -155,10 +155,9 @@ static inline HGLRC gl_init_basic_context(HDC hdc)
|
|||
|
||||
static const int attribs[] =
|
||||
{
|
||||
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
WGL_CONTEXT_MINOR_VERSION_ARB, 2,
|
||||
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB |
|
||||
WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
#ifdef _DEBUG
|
||||
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
|
||||
#endif
|
||||
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0, 0
|
||||
};
|
||||
|
@ -244,29 +243,11 @@ static bool gl_init_extensions(device_t device)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!GLEW_VERSION_2_1) {
|
||||
blog(LOG_ERROR, "OpenGL 2.1 minimum required by the graphics "
|
||||
"adapter");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GLEW_ARB_framebuffer_object) {
|
||||
required_extension_error("GL_ARB_framebuffer_object");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WGLEW_ARB_pixel_format) {
|
||||
required_extension_error("WGL_ARB_pixel_format");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GLEW_ARB_copy_image)
|
||||
device->copy_type = COPY_TYPE_ARB;
|
||||
else if (GLEW_NV_copy_image)
|
||||
device->copy_type = COPY_TYPE_NV;
|
||||
else
|
||||
device->copy_type = COPY_TYPE_FBO_BLIT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -377,19 +358,6 @@ static bool init_default_swap(struct gl_platform *plat, device_t device,
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
static void APIENTRY gl_debug_message_amd(GLuint id,
|
||||
GLenum category,
|
||||
GLenum severity,
|
||||
GLsizei length,
|
||||
const GLchar *msg,
|
||||
void *param)
|
||||
{
|
||||
OutputDebugStringA(msg);
|
||||
OutputDebugStringA("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
void gl_update(device_t device)
|
||||
{
|
||||
/* does nothing on windows */
|
||||
|
@ -425,19 +393,6 @@ struct gl_platform *gl_platform_create(device_t device,
|
|||
if (!plat->hrc)
|
||||
goto fail;
|
||||
|
||||
if (GLEW_ARB_seamless_cube_map) {
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
gl_success("GL_TEXTURE_CUBE_MAP_SEAMLESS");
|
||||
}
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (GLEW_AMD_debug_output) {
|
||||
glDebugMessageEnableAMD(0, 0, 0, NULL, true);
|
||||
glDebugMessageCallbackAMD(gl_debug_message_amd, device);
|
||||
gl_success("glDebugMessageCallback");
|
||||
}
|
||||
#endif
|
||||
|
||||
return plat;
|
||||
|
||||
fail:
|
||||
|
|
|
@ -19,12 +19,11 @@ static const GLenum fb_attribs[] = {
|
|||
};
|
||||
|
||||
static const GLenum ctx_attribs[] = {
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 2,
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB |
|
||||
GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
|
||||
#ifdef _DEBUG
|
||||
GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_DEBUG_BIT_ARB,
|
||||
#endif
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
0, 0
|
||||
None,
|
||||
};
|
||||
|
||||
static const char* __GLX_error_table[] = {
|
||||
|
@ -106,24 +105,14 @@ static void print_info_stuff(struct gs_init_data *info)
|
|||
struct gl_platform *gl_platform_create(device_t device,
|
||||
struct gs_init_data *info)
|
||||
{
|
||||
/* X11 */
|
||||
int num_configs = 0;
|
||||
int error_base = 0, event_base = 0;
|
||||
Display *display = XOpenDisplay(NULL); /* Open default screen */
|
||||
|
||||
/* OBS */
|
||||
struct gl_platform *plat = bmalloc(sizeof(struct gl_platform));
|
||||
|
||||
/* GLX */
|
||||
GLXFBConfig* configs;
|
||||
|
||||
print_info_stuff(info);
|
||||
|
||||
if (!plat) {
|
||||
blog(LOG_ERROR, "Out of memory");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(plat, 0, sizeof(struct gl_platform));
|
||||
|
||||
if (!display) {
|
||||
|
@ -139,6 +128,17 @@ struct gl_platform *gl_platform_create(device_t device,
|
|||
|
||||
XSetErrorHandler(GLXErrorHandler);
|
||||
|
||||
/* We require glX version 1.4 */
|
||||
{
|
||||
int major = 0, minor = 0;
|
||||
|
||||
glXQueryVersion(display, &major, &minor);
|
||||
if (major < 1 || minor < 4) {
|
||||
blog(LOG_ERROR, "GLX version found: %i.%i\nRequired: 1.4", major, minor);
|
||||
goto fail0;
|
||||
}
|
||||
}
|
||||
|
||||
glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)glXGetProcAddress("glXCreateContextAttribsARB");
|
||||
if (!glXCreateContextAttribsARB) {
|
||||
blog(LOG_ERROR, "ARB_GLX_create_context not supported!");
|
||||
|
@ -169,20 +169,18 @@ struct gl_platform *gl_platform_create(device_t device,
|
|||
goto fail2;
|
||||
}
|
||||
|
||||
blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));
|
||||
|
||||
/* Initialize GLEW */
|
||||
{
|
||||
{
|
||||
glewExperimental = true;
|
||||
GLenum err = glewInit();
|
||||
|
||||
if (GLEW_OK != err) {
|
||||
blog(LOG_ERROR, glewGetErrorString(err));
|
||||
goto fail2;
|
||||
}
|
||||
}
|
||||
|
||||
glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
|
||||
glEnable(GL_DEBUG_OUTPUT);
|
||||
glEnable(GL_CULL_FACE);
|
||||
blog(LOG_INFO, "OpenGL version: %s\n", glGetString(GL_VERSION));
|
||||
|
||||
plat->swap.device = device;
|
||||
plat->swap.info = *info;
|
||||
|
@ -195,6 +193,7 @@ struct gl_platform *gl_platform_create(device_t device,
|
|||
return plat;
|
||||
|
||||
fail2:
|
||||
glXMakeCurrent(display, None, NULL);
|
||||
glXDestroyContext(display, plat->context);
|
||||
fail1:
|
||||
XFree(configs);
|
||||
|
@ -236,6 +235,12 @@ void device_leavecontext(device_t device)
|
|||
blog(LOG_ERROR, "Failed to reset current context.");
|
||||
}
|
||||
}
|
||||
|
||||
void gl_update(device_t device)
|
||||
{
|
||||
/* I don't know of anything we can do here. */
|
||||
}
|
||||
|
||||
void device_load_swapchain(device_t device, swapchain_t swap)
|
||||
{
|
||||
if(!swap)
|
||||
|
|
Loading…
Reference in New Issue