opengl_x11

Playing with OpenGL
git clone git://bsandro.tech/opengl_x11
Log | Files | Refs | README | LICENSE

main3.c (3714B)


      1 #include <stdint.h>
      2 
      3 #include <X11/Xlib.h>
      4 #include <X11/XKBlib.h>
      5 #include <GL/glx.h>
      6 #include <GL/gl.h>
      7 #include <dlfcn.h>
      8 #include <stdio.h>
      9 #include <sys/syscall.h>
     10 #include <time.h>
     11 
     12 #define SCRW 800
     13 #define SCRH 600
     14 
     15 static __inline long __syscall2(long n, long a1, long a2)
     16 {
     17     unsigned long ret;
     18     __asm__ __volatile__ ("syscall" : "=a"(ret) : "a"(n), "D"(a1), "S"(a2)
     19             : "rcx", "r11", "memory");
     20     return ret;
     21 }
     22 
     23 static __inline uint64_t time_monotonic(void)
     24 {
     25     struct timespec now;
     26     __syscall2(SYS_clock_gettime, CLOCK_MONOTONIC_RAW, (long)&now);
     27     return now.tv_sec * 1000000 + now.tv_nsec / 1000;
     28 }
     29 
     30 static int visual_hints[] = {
     31     GLX_RGBA,
     32     GLX_DEPTH_SIZE, 24,
     33     GLX_DOUBLEBUFFER,
     34     None
     35 };
     36 
     37 static const char *sym_names =
     38 "libX11.so\0"
     39 "XOpenDisplay\0"
     40 "XCreateSimpleWindow\0"
     41 "XSelectInput\0"
     42 "XMapWindow\0"
     43 "XPending\0"
     44 "XNextEvent\0"
     45 "XkbKeycodeToKeysym\0"
     46 "\0"
     47 "libGL.so\0"
     48 "glXChooseVisual\0"
     49 "glXCreateContext\0"
     50 "glXMakeCurrent\0"
     51 "glXSwapBuffers\0"
     52 "glClear\0\0\0";
     53 
     54 static void *syms[12];
     55 
     56 #define _XOpenDisplay        ((Display *(*)(const char *))syms[0])
     57 #define _XCreateSimpleWindow ((Window (*)(Display *, Window, int, int, unsigned, unsigned, unsigned, unsigned long, unsigned long))syms[1])
     58 #define _XSelectInput        ((int (*)(Display *, Window, long))syms[2])
     59 #define _XMapWindow          ((int (*)(Display *, Window))syms[3])
     60 #define _XPending            ((int (*)(Display *))syms[4])
     61 #define _XNextEvent          ((int (*)(Display *, XEvent *))syms[5])
     62 #define _XkbKeycodeToKeysym  ((KeySym (*)(Display *, KeyCode, int, int))syms[6])
     63 
     64 #define _glXChooseVisual     ((XVisualInfo *(*)(Display *, int, int *))syms[7])
     65 #define _glXCreateContext    ((GLXContext (*)(Display *, XVisualInfo *, GLXContext, Bool))syms[8])
     66 #define _glXMakeCurrent      ((Bool (*)(Display *, GLXDrawable, GLXContext))syms[9])
     67 #define _glXSwapBuffers      ((void (*)(Display *, GLXDrawable))syms[10])
     68 
     69 #define _glClear             ((void (*)(GLbitfield))syms[11])
     70 
     71 static void dl_load(void)
     72 {
     73     const char *name = sym_names;
     74     void **sym = syms;
     75 
     76     do
     77     {
     78         void *dl = dlopen(name, RTLD_LAZY | RTLD_GLOBAL);
     79         for(;;)
     80         {
     81             while(*name++);
     82             if(*name == 0) break;
     83             *sym++ = dlsym(dl, name);
     84         }
     85     } while(*++name);
     86 }
     87 
     88 void my_main(int argc, const char **argv)
     89 {
     90     dl_load();
     91 
     92     Display *display = _XOpenDisplay(NULL);
     93     int screen = DefaultScreen(display);
     94     Window window = _XCreateSimpleWindow(display, RootWindow(display, screen), 0, 0, SCRW, SCRH, 0, 0, 0);
     95     _XSelectInput(display, window, KeyPressMask | KeyReleaseMask);
     96     XVisualInfo *visual_info = _glXChooseVisual(display, screen, visual_hints);
     97     GLXContext context = _glXCreateContext(display, visual_info, NULL, True);
     98     _glXMakeCurrent(display, window, context);
     99 
    100     _XMapWindow(display, window);
    101 
    102     uint64_t prev = time_monotonic();
    103     uint64_t t = 0;
    104     for(;;)
    105     {
    106         XEvent event;
    107         while(_XPending(display))
    108         {
    109             _XNextEvent(display, &event);
    110             if(event.type == KeyPress)
    111             {
    112                 switch(_XkbKeycodeToKeysym(display, event.xkey.keycode, 0, 0))
    113                 {
    114                     case XK_Escape: goto shutdown;
    115                 }
    116             }
    117         }
    118         // draw demo
    119 
    120         _glClear(GL_COLOR_BUFFER_BIT);
    121 
    122         _glXSwapBuffers(display, window);
    123 
    124         t += time_monotonic() - prev;
    125     }
    126 
    127 shutdown:
    128     return;
    129 }
    130 
    131 asm (
    132     ".text\n"
    133     ".global _start\n"
    134     "_start:\n"
    135     "xor %rbp,%rbp\n"
    136     "pop %rdi\n"
    137     "mov %rsp,%rsi\n"
    138     "andq $-16,%rsp\n"
    139     "call my_main\n"
    140     "movq $60,%rax\n"
    141     "xor %rdi,%rdi\n"
    142     "syscall\n"
    143 );