summaryrefslogtreecommitdiff
path: root/example
diff options
context:
space:
mode:
authorpryazha <pryadeiniv@mail.ru>2025-10-12 15:25:23 +0500
committerpryazha <pryadeiniv@mail.ru>2025-10-12 15:25:23 +0500
commit818f818f583881156eb279c71b1359bf2c4f3580 (patch)
tree874e8d2fdc5334bc70925aa87923791f7662ddb8 /example
parent3cf987880e384140bf996c37f820ddeea38bc60e (diff)
change identation, maybe will change back, add own gl functions loading, and glx example
Diffstat (limited to 'example')
-rwxr-xr-xexample/b40
-rwxr-xr-xexample/linuxbin0 -> 63392 bytes
-rw-r--r--example/linux.c308
-rw-r--r--example/simple.c16
4 files changed, 364 insertions, 0 deletions
diff --git a/example/b b/example/b
new file mode 100755
index 0000000..4ccb9a4
--- /dev/null
+++ b/example/b
@@ -0,0 +1,40 @@
+#!/bin/sh
+
+echorun()
+{
+ echo $1
+ $1
+}
+
+compile()
+{
+ echorun "$cc -c $cflags $include $lflags -o $1.o $1.c $libs"
+}
+
+compile_and_link()
+{
+ echorun "$cc $cflags $include $lflags -o $1 $1.c $libs"
+}
+
+start=`pwd`
+dir=`realpath $0`
+dir=`dirname $dir`
+
+echorun "cd $dir"
+
+if [ "$1" = 'clean' ] ; then
+ echorun "rm -f *.o linux"
+ echorun "cd $start"
+ exit
+fi
+
+cc='gcc'
+cflags='-g'
+
+include="-I../../prb -I../../prge"
+lflags="-L../../prb -L../../prge"
+libs='-lprb -lprge -lGL -lX11 -lm'
+
+compile_and_link linux
+
+echorun "cd $start"
diff --git a/example/linux b/example/linux
new file mode 100755
index 0000000..f244e76
--- /dev/null
+++ b/example/linux
Binary files differ
diff --git a/example/linux.c b/example/linux.c
new file mode 100644
index 0000000..48be3a2
--- /dev/null
+++ b/example/linux.c
@@ -0,0 +1,308 @@
+#include <GL/glx.h>
+#include "types.h"
+#include "sys.h"
+#include <string.h>
+#include <sys/time.h>
+#include "gldefs.h"
+#include "context.h"
+
+#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
+#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
+
+typedef GLXContext (*glXCreateContextAttribsARBProc)(Display*, GLXFBConfig, GLXContext, Bool, const int*);
+
+struct xcontext {
+ Display *dpy;
+ Window win;
+ i32 w;
+ i32 h;
+ i32 stop;
+ f64 last_time;
+ f64 time;
+ f64 dt;
+};
+
+static GLXFBConfig
+find_best_fbconfig(Display *dpy, i32 *attribs)
+{
+ i32 fbcount;
+ GLXFBConfig *fbconfigs = glXChooseFBConfig(dpy, DefaultScreen(dpy), attribs, &fbcount);
+ if (!fbconfigs)
+ die("failed to retrieve a framebuffer configs");
+ i32 best = 0, best_samples = 0;
+ for (i32 i = 0; i < fbcount; i++) {
+ XVisualInfo *vi = glXGetVisualFromFBConfig(dpy, fbconfigs[i]);
+ if (!vi)
+ continue;
+ i32 buffers, samples;
+ glXGetFBConfigAttrib(dpy, fbconfigs[i], GLX_SAMPLE_BUFFERS, &buffers);
+ glXGetFBConfigAttrib(dpy, fbconfigs[i], GLX_SAMPLES, &samples);
+ if (buffers && samples > best_samples) {
+ best = i;
+ best_samples = samples;
+ }
+ XFree(vi);
+ }
+ GLXFBConfig fbconfig = fbconfigs[best];
+ XFree(fbconfigs);
+ return fbconfig;
+}
+
+static GLXContext
+create_gl_context(struct xcontext xctx, GLXFBConfig fbconfig)
+{
+ const char *extensions = glXQueryExtensionsString(xctx.dpy, DefaultScreen(xctx.dpy));
+ glXCreateContextAttribsARBProc glXCreateContextAttribsARB = 0;
+ glXCreateContextAttribsARB = (glXCreateContextAttribsARBProc)glXGetProcAddressARB("glXCreateContextAttribsARB");
+ if (!strstr(extensions, "GLX_ARB_create_context") || !glXCreateContextAttribsARB)
+ die("glXCreateContextAttribsARB not found");
+ i32 context_attribs[] = {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 3,
+ None
+ };
+ GLXContext ctx = glXCreateContextAttribsARB(xctx.dpy, fbconfig, 0, 1, context_attribs);
+ XFree(fbconfig);
+ if (!ctx)
+ die("failed to create gl 3.3 context ");
+ return ctx;
+}
+
+static f64
+get_time(void)
+{
+ struct timeval tv;
+ gettimeofday(&tv, 0);
+ return (f64)tv.tv_sec + tv.tv_usec / 1000000.0;
+}
+
+#define check_gl_function(f) if (!#f) die("failed to load #f");
+
+static void
+check_gl_functions(void)
+{
+ check_gl_function(gl_create_shader);
+
+ if (!gl_create_shader)
+ die("failed to load glCreateShader");
+ if (!gl_clear_color)
+ die("failed to load glClearColor");
+ if (!gl_clear)
+ die("failed to load glClear");
+ if (!gl_viewport)
+ die("failed to load glViewport");
+ if (!gl_gen_vertex_arrays)
+ die("failed to load glGenVertexArrays");
+ if (!gl_delete_vertex_arrays)
+ die("failed to load glDeleteVertexArrays");
+ if (!gl_bind_vertex_array)
+ die("failed to load glBindVertexArray");
+ if (!gl_enable_vertex_attrib_array)
+ die("failed to load glEnableVertexAttribArray");
+ if (!gl_disable_vertex_attrib_array)
+ die("failed to load glDisableVertexAttribArray");
+ if (!gl_vertex_attrib_pointer)
+ die("failed to load glVertexAttribPointer");
+ if (!gl_gen_buffers)
+ die("failed to load glGenBuffers");
+ if (!gl_delete_buffers)
+ die("failed to load glDeleteBuffers");
+ if (!gl_bind_buffer)
+ die("failed to load glBindBuffer");
+ if (!gl_buffer_data)
+ die("failed to load glBufferData");
+ if (!gl_create_shader)
+ die("failed to load glCreateShader");
+ if (!gl_delete_shader)
+ die("failed to load glDeleteShader");
+ if (!gl_shader_source)
+ die("failed to load glShaderSource");
+ if (!gl_compile_shader)
+ die("failed to load glCompileShader");
+ if (!gl_get_shader_iv)
+ die("failed to load glGetShaderiv");
+ if (!gl_get_shader_info_log)
+ die("failed to load glGetShaderInfoLog");
+ if (!gl_create_program)
+ die("failed to load glCreateProgram");
+ if (!gl_attach_shader)
+ die("failed to load glAttachShader");
+ if (!gl_link_program)
+ die("failed to load glLinkProgram");
+ if (!gl_use_program)
+ die("failed to load glUseProgram");
+ if (!gl_get_uniform_location)
+ die("failed to load glGetUniformLocation");
+ if (!gl_uniform_matrix4fv)
+ die("failed to load glUniformMatrix4fv");
+ if (!gl_get_program_iv)
+ die("failed to load glGetProgramiv");
+ if (!gl_get_program_info_log)
+ die("failed to load glGetProgramInfoLog");
+ if (!gl_draw_arrays)
+ die("failed to load glDrawArrays");
+}
+
+void
+load_gl_functions(void)
+{
+ gl_clear_color = (void (*)(f32, f32, f32, f32))glXGetProcAddress("glClearColor");
+ gl_clear = (void (*)(u32))glXGetProcAddress("glClear");
+
+ gl_viewport = (void (*)(i32, i32, i32, i32))glXGetProcAddress("glViewport");
+
+ gl_gen_vertex_arrays = (void (*)(i32, u32 *))glXGetProcAddress("glGenVertexArrays");
+ gl_delete_vertex_arrays = (void (*)(i32, const u32 *))glXGetProcAddress("glDeleteVertexArrays");
+ gl_bind_vertex_array = (void (*)(u32))glXGetProcAddress("glBindVertexArray");
+ gl_enable_vertex_attrib_array = (void (*)(u32))glXGetProcAddress("glEnableVertexAttribArray");
+ gl_disable_vertex_attrib_array = (void (*)(u32))glXGetProcAddress("glDisableVertexAttribArray");
+ gl_vertex_attrib_pointer = (void (*)(u32, i32, u32, u8, i32, const void *))glXGetProcAddress("glVertexAttribPointer");
+
+ gl_gen_buffers = (void (*)(i32, u32 *))glXGetProcAddress("glGenBuffers");
+ gl_delete_buffers = (void (*)(i32, const u32 *))glXGetProcAddress("glDeleteBuffers");
+ gl_bind_buffer = (void (*)(u32, u32))glXGetProcAddress("glBindBuffer");
+ gl_buffer_data = (void (*)(u32, i64, const void *, u32))glXGetProcAddress("glBufferData");
+
+ gl_create_shader = (u32 (*)(u32))glXGetProcAddress("glCreateShader");
+ gl_delete_shader = (void (*)(u32))glXGetProcAddress("glDeleteShader");
+ gl_shader_source = (void (*)(u32, i32, const char *const *, const i32 *))glXGetProcAddress("glShaderSource");
+ gl_compile_shader = (void (*)(u32))glXGetProcAddress("glCompileShader");
+ gl_get_shader_iv = (void (*)(u32, u32, i32 *))glXGetProcAddress("glGetShaderiv");
+ gl_get_shader_info_log = (void (*)(u32, i32, i32 *, char *))glXGetProcAddress("glGetShaderInfoLog");
+
+ gl_create_program = (u32 (*)(void))glXGetProcAddress("glCreateProgram");
+ gl_attach_shader = (void (*)(u32, u32))glXGetProcAddress("glAttachShader");
+ gl_link_program = (void (*)(u32))glXGetProcAddress("glLinkProgram");
+ gl_use_program = (void (*)(u32))glXGetProcAddress("glUseProgram");
+
+ gl_get_uniform_location = (i32 (*)(u32, const char *))glXGetProcAddress("glGetUniformLocation");
+ gl_uniform_matrix4fv = (void (*)(i32, i32, u8, const f32 *))glXGetProcAddress("glUniformMatrix4fv");
+ gl_get_program_iv = (void (*)(u32, u32, i32 *))glXGetProcAddress("glGetProgramiv");
+ gl_get_program_info_log = (void (*)(u32, i32, i32 *, char *))glXGetProcAddress("glGetProgramInfoLog");
+
+ gl_draw_arrays = (void (*)(u32, i32, i32))glXGetProcAddress("glDrawArrays");
+
+ check_gl_functions();
+}
+
+static struct xcontext
+xinit(struct prge_context prge, const char *name)
+{
+ struct xcontext xctx = {0};
+ Display *dpy = XOpenDisplay(0);
+ if (!dpy)
+ die("failed to open x dpy");
+ xctx.dpy = dpy;
+ i32 major, minor;
+ if (!glXQueryVersion(dpy, &major, &minor))
+ die("failed to get glx version");
+ if ((major < 1) || ((major == 1) && (minor < 3)))
+ die("invalid glx version");
+ i32 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_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, True,
+ None
+ };
+ GLXFBConfig fbconfig = find_best_fbconfig(dpy, attribs);
+ XVisualInfo *vi = glXGetVisualFromFBConfig(dpy, fbconfig);
+ XSetWindowAttributes swattribs = {0};
+ swattribs.colormap = XCreateColormap(dpy, RootWindow(dpy, vi->screen),
+ vi->visual, AllocNone);
+ swattribs.event_mask = StructureNotifyMask | KeyPressMask;
+ Window root = RootWindow(xctx.dpy, vi->screen);
+ u32 flags = CWBorderPixel | CWColormap | CWEventMask;
+ xctx.w = prge.width;
+ xctx.h = prge.height;
+ xctx.win = XCreateWindow(xctx.dpy, root, 0, 0, xctx.w, xctx.h, 0, vi->depth,
+ InputOutput, vi->visual, flags, &swattribs);
+ if (!xctx.win)
+ die("failed to create window");
+ XFree(vi);
+ XStoreName(xctx.dpy, xctx.win, name);
+ XMapWindow(xctx.dpy, xctx.win);
+ GLXContext glctx = create_gl_context(xctx, fbconfig);
+ glXMakeCurrent(xctx.dpy, xctx.win, glctx);
+ load_gl_functions();
+
+ i32 (*glXGetSwapInterval)(void) = 0;
+ i32 (*glXSwapInterval)(u32) = 0;
+ glXGetSwapInterval = (i32 (*)(void))glXGetProcAddressARB("glXGetSwapIntervalMESA");
+ glXSwapInterval = (i32 (*)(u32))glXGetProcAddressARB("glXSwapIntervalMESA");
+ if (glXGetSwapInterval && glXSwapInterval) {
+ i32 swap_interval = glXGetSwapInterval();
+ info("swap interval %d", swap_interval);
+ i32 swap = glXSwapInterval(0);
+ swap_interval = glXGetSwapInterval();
+ info("swap %d interval %d", swap, swap_interval);
+ } else {
+ info("cannot get swap interval");
+ }
+
+ xctx.last_time = get_time();
+ return xctx;
+}
+
+void
+handle_keyboard(struct xcontext *xctx, i32 code)
+{
+ switch (code) {
+ case XK_Escape:
+ xctx->stop = 1;
+ break;
+ }
+}
+
+void
+handle_events(struct xcontext *xctx)
+{
+ while (XPending(xctx->dpy)) {
+ XEvent ev;
+ XNextEvent(xctx->dpy, &ev);
+ switch (ev.type) {
+ case KeyPress:
+ handle_keyboard(xctx, XLookupKeysym(&ev.xkey, 0));
+ break;
+ case ConfigureNotify:
+ info("%d %d", ev.xconfigure.width, ev.xconfigure.height);
+ gl_viewport(0, 0, ev.xconfigure.width, ev.xconfigure.height);
+ break;
+ }
+ }
+}
+
+static void
+update_time(struct xcontext *xctx)
+{
+ f64 current_time = get_time();
+ xctx->dt = current_time - xctx->last_time;
+ xctx->time += xctx->dt;
+ xctx->last_time = current_time;
+}
+
+i32
+main(void)
+{
+ struct prge_context prge = init_prge(800, 600);
+ struct xcontext xctx = xinit(prge, "loadgl");
+ f64 ms = 16.666;
+ f64 last = get_time();
+ f64 dt = 0.0;
+ while (!xctx.stop) {
+ handle_events(&xctx);
+ update_time(&xctx);
+ info("%f", xctx.dt);
+ gl_clear_color(0.16f, 0.16f, 0.16f, 1.0f);
+ gl_clear(gl_color_buffer_bit);
+ glXSwapBuffers(xctx.dpy, xctx.win);
+ }
+ return 0;
+}
diff --git a/example/simple.c b/example/simple.c
new file mode 100644
index 0000000..b53b47b
--- /dev/null
+++ b/example/simple.c
@@ -0,0 +1,16 @@
+void
+init(struct prge_context *prge_ctx)
+{
+}
+
+void
+update(struct prge_context *prge_ctx, f32 dt)
+{
+}
+
+void
+render(struct prge_context prge_ctx)
+{
+ gl_clear_color(0.18f, 0.18f, 0.18f, 1.0f);
+ gl_clear(gl_color_buffer_bit);
+}