sketch out first bit of linux-backend of opengl-backend

This commit is contained in:
Ryan Fleury
2025-05-09 21:51:48 -07:00
parent 5939c3f010
commit a1318e6117
8 changed files with 205 additions and 19 deletions
@@ -0,0 +1,110 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
internal VoidProc *
r_ogl_os_load_procedure(char *name)
{
VoidProc *result = (VoidProc *)glXGetProcAddressARB((U8 *)name);
return result;
}
internal void
r_ogl_os_init(CmdLine *cmdln)
{
//- rjf: require GLX 1.3+
int glx_version_major = 0;
int glx_version_minor = 0;
if(!glXQueryVersion(os_lnx_gfx_state->display, &glx_version_major, &glx_version_minor) ||
(glx_version_major == 1 && glx_version_minor < 3) ||
glx_version_major < 1)
{
Temp scratch = scratch_begin(0, 0);
String8 message = push_str8f(scratch.arena, "Unsupported GLX version (%i.%i, need at least 1.3)", glx_version_major, glx_version_minor);
os_graphical_message(1, str8_lit("Fatal Error"), message);
os_abort(1);
scratch_end(scratch);
}
//- rjf: get frame buffer configs
local_persist int framebuffer_config_options[] =
{
GLX_X_RENDERABLE, 1,
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
GLX_RENDER_TYPE, GLX_RGBA_BIT,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 8,
GLX_GREEN_SIZE, 8,
GLX_BLUE_SIZE, 8,
GLX_ALPHA_SIZE, 8,
GLX_DEPTH_SIZE, 24,
GLX_STENCIL_SIZE, 8,
GLX_DOUBLEBUFFER, 1,
None
};
int framebuffer_configs_count = 0;
GLXFBConfig *framebuffer_configs = glXChooseFBConfig(os_lnx_gfx_state->display, DefaultScreen(os_lnx_gfx_state->display), framebuffer_config_options, &framebuffer_configs_count);
if(framebuffer_configs == 0)
{
os_graphical_message(1, str8_lit("Fatal Error"), str8_lit("Could not find a suitable framebuffer configuration."));
os_abort(1);
}
GLXFBConfig framebuffer_config = framebuffer_configs[0];
XFree(framebuffer_configs);
//- rjf: get visual info; create color map
XVisualInfo *visual_info = glXGetVisualFromFBConfig(os_lnx_gfx_state->display, framebuffer_config);
Colormap cmap = XCreateColormap(os_lnx_gfx_state->display, RootWindow(os_lnx_gfx_state->display, visual_info->screen), visual_info->visual, AllocNone);
//- rjf: construct set-window-attributes
XSetWindowAttributes set_window_attributes = {0};
set_window_attributes.background_pixmap = None;
set_window_attributes.border_pixel = 0;
set_window_attributes.event_mask = StructureNotifyMask;
//- rjf: construct context
{
B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug"));
#if BUILD_DEBUG
debug_mode = 1;
#endif
glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB((U8 *)"glXCreateContextAttribsARB");
int context_options[] =
{
GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
GLX_CONTEXT_MINOR_VERSION_ARB, 3,
GLX_CONTEXT_FLAGS_ARB, !!debug_mode*GLX_CONTEXT_DEBUG_BIT_ARB,
None
};
r_ogl_lnx_ctx = glXCreateContextAttribsARB(os_lnx_gfx_state->display, framebuffer_config, 0, 1, context_options);
}
glXMakeCurrent(os_lnx_gfx_state->display, None, r_ogl_lnx_ctx);
}
internal R_Handle
r_ogl_os_window_equip(OS_Handle window)
{
R_Handle result = {0};
return result;
}
internal void
r_ogl_os_window_unequip(OS_Handle os, R_Handle r)
{
}
internal void
r_ogl_os_select_window(OS_Handle os, R_Handle r)
{
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
glXMakeCurrent(os_lnx_gfx_state->display, w->window, r_ogl_lnx_ctx);
}
internal void
r_ogl_os_window_swap(OS_Handle os, R_Handle r)
{
OS_LNX_Window *w = (OS_LNX_Window *)os.u64[0];
glXSwapBuffers(os_lnx_gfx_state->display, w->window);
}
@@ -0,0 +1,25 @@
// Copyright (c) 2024 Epic Games Tools
// Licensed under the MIT license (https://opensource.org/license/mit/)
#ifndef RENDER_OPENGL_LINUX_H
#define RENDER_OPENGL_LINUX_H
#define glTexImage3D glTexImage3D__static
#define glTexSubImage3D glTexSubImage3D__static
#define glActiveTexture glActiveTexture__static
#include <GL/gl.h>
#include <GL/glx.h>
#undef glTexImage3D
#undef glTexSubImage3D
#undef glActiveTexture
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
#define GLX_CONTEXT_FLAGS_ARB 0x2094
#define GLX_CONTEXT_DEBUG_BIT_ARB 0x00000001
#define GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002
typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
global GLXContext r_ogl_lnx_ctx = 0;
#endif // RENDER_OPENGL_LINUX_H
+16 -6
View File
@@ -6,6 +6,8 @@
#if OS_WINDOWS
# include "render/opengl/win32/render_opengl_win32.c"
#elif OS_LINUX
# include "render/opengl/linux/render_opengl_linux.c"
#else
# error OS portion of OpenGL rendering backend not defined.
#endif
@@ -67,6 +69,7 @@ internal void
r_ogl_debug_message_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam)
{
raddbg_log("[OpenGL] %.*s\n", (int)length, message);
fprintf(stderr, "[OpenGL] %.*s\n", (int)length, message);
}
////////////////////////////////
@@ -103,7 +106,7 @@ r_init(CmdLine *cmdln)
{
stages[idx].out = glCreateShader(stages[idx].type);
GLint src_size = stages[idx].src->size;
glShaderSource(stages[idx].out, 1, &stages[idx].src->str, &src_size);
glShaderSource(stages[idx].out, 1, (char **)&stages[idx].src->str, &src_size);
glCompileShader(stages[idx].out);
GLint info_log_length = 0;
GLint status = 0;
@@ -113,7 +116,7 @@ r_init(CmdLine *cmdln)
{
stages[idx].errors.str = push_array(r_ogl_state->arena, U8, info_log_length+1);
stages[idx].errors.size = info_log_length;
glGetShaderInfoLog(stages[idx].out, info_log_length, 0, stages[idx].errors.str);
glGetShaderInfoLog(stages[idx].out, info_log_length, 0, (char *)stages[idx].errors.str);
}
raddbg_pin(text(stages[idx].errors.str));
}
@@ -129,14 +132,14 @@ r_init(CmdLine *cmdln)
R_OGL_AttributeArray inputs = r_ogl_shader_kind_input_attributes_table[k];
for EachIndex(idx, inputs.count)
{
glBindAttribLocation(program, inputs.v[idx].index, inputs.v[idx].name.str);
glBindAttribLocation(program, inputs.v[idx].index, (char *)inputs.v[idx].name.str);
}
// rjf: bind outputs
R_OGL_AttributeArray outputs = r_ogl_shader_kind_output_attributes_table[k];
for EachIndex(idx, outputs.count)
{
glBindFragDataLocation(program, outputs.v[idx].index, outputs.v[idx].name.str);
glBindFragDataLocation(program, outputs.v[idx].index, (char *)outputs.v[idx].name.str);
}
// rjf: link / validate / store
@@ -158,8 +161,15 @@ r_init(CmdLine *cmdln)
glEnable(GL_FRAMEBUFFER_SRGB);
//- rjf: set up debug callback
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(r_ogl_debug_message_callback, 0);
B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug"));
#if BUILD_DEBUG
debug_mode = 1;
#endif
if(debug_mode)
{
glEnable(GL_DEBUG_OUTPUT);
glDebugMessageCallback(r_ogl_debug_message_callback, 0);
}
}
//- rjf: window setup/teardown
+2
View File
@@ -9,6 +9,8 @@
#if OS_WINDOWS
# include "render/opengl/win32/render_opengl_win32.h"
#elif OS_LINUX
# include "render/opengl/linux/render_opengl_linux.h"
#else
# error OS portion of OpenGL rendering backend not defined.
#endif
@@ -78,11 +78,15 @@ r_ogl_os_init(CmdLine *cmdline)
HGLRC real_ctx = 0;
if(pf)
{
const int context_attribs[] =
B32 debug_mode = cmd_line_has_flag(cmdln, str8_lit("opengl_debug"));
#if BUILD_DEBUG
debug_mode = 1;
#endif
int context_attribs[] =
{
WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
WGL_CONTEXT_MINOR_VERSION_ARB, 3,
WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_DEBUG_BIT_ARB,
WGL_CONTEXT_FLAGS_ARB, !!debug_mode*WGL_CONTEXT_DEBUG_BIT_ARB,
0
};
real_ctx = wglCreateContextAttribsARB(dc, bootstrap_ctx, context_attribs);