├── .gitignore ├── .gitmodules ├── Makefile ├── README.md ├── gtk-opengl.c ├── index.html ├── index.html.inc ├── sdl2-opengl.c ├── shader.frag ├── shader_minifier.exe └── xlib-opengl.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.elf 2 | gtk-webkit 3 | gtk-opengl 4 | xlib-opengl 5 | sdl2-opengl 6 | shader.h -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "vondehi"] 2 | path = vondehi 3 | url = https://gitlab.com/PoroCYon/vondehi.git 4 | [submodule "Section-Header-Stripper"] 5 | path = Section-Header-Stripper 6 | url = https://github.com/blackle/Section-Header-Stripper 7 | [submodule "noelfver"] 8 | path = noelfver 9 | url = https://gitlab.com/PoroCYon/noelfver 10 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | DEBUG=false 3 | 4 | CFLAGS := -fno-plt -O1 -std=gnu11 -nostartfiles -Wall -Wextra 5 | CFLAGS += -fno-stack-protector -fno-stack-check -fno-unwind-tables -fno-asynchronous-unwind-tables -fomit-frame-pointer 6 | CFLAGS += -no-pie -fno-pic -fno-PIE -fno-PIC -march=core2 -ffunction-sections -fdata-sections 7 | 8 | ifeq ($(DEBUG),false) 9 | CFLAGS += -nostdlib 10 | else 11 | CFLAGS += -DDEBUG=true 12 | endif 13 | 14 | .PHONY: clean checkgccversion noelfver 15 | 16 | all : checkgccversion gtk-opengl xlib-opengl sdl2-opengl 17 | 18 | noelfver: 19 | make -C noelfver 20 | 21 | checkgccversion : 22 | ifneq ($(shell expr `gcc -dumpversion`),8.3.0) 23 | $(error GCC version must be 8.3.0) 24 | endif 25 | 26 | packer : vondehi/vondehi.asm 27 | cd vondehi; nasm -fbin -o vondehi vondehi.asm 28 | 29 | shader.h : shader.frag Makefile 30 | mono ./shader_minifier.exe --preserve-externals shader.frag -o shader.h 31 | 32 | gtk-opengl.elf : gtk-opengl.c shader.h Makefile 33 | gcc -o $@ $< `pkg-config --cflags gtk+-3.0` -lGL -lgtk-3 -lgdk-3 -lgobject-2.0 $(CFLAGS) 34 | 35 | xlib-opengl.elf : xlib-opengl.c shader.h Makefile 36 | gcc -o $@ $< -lX11 -lGL -lXrandr $(CFLAGS) 37 | 38 | sdl2-opengl.elf : sdl2-opengl.c shader.h Makefile 39 | gcc -o $@ $< -lSDL2 -lGL $(CFLAGS) 40 | 41 | gtk-opengl : gtk-opengl_opt.elf.packed 42 | mv $< $@ 43 | 44 | xlib-opengl : xlib-opengl_opt.elf.packed 45 | mv $< $@ 46 | 47 | sdl2-opengl : sdl2-opengl_opt.elf.packed 48 | mv $< $@ 49 | 50 | index.html.inc : index.html 51 | cat index.html | xxd -i > index.html.inc 52 | echo ", 0" >> index.html.inc 53 | 54 | #all the rest of these rules just takes a compiled elf file and generates a packed version of it with vondehi 55 | %_opt.elf : %.elf Makefile noelfver 56 | cp $< $@ 57 | strip $@ 58 | strip -R .note -R .comment -R .eh_frame -R .eh_frame_hdr -R .note.gnu.build-id -R .got -R .got.plt -R .gnu.version -R .shstrtab -R .gnu.version_r -R .gnu.hash $@ 59 | ./noelfver/noelfver $@ > $@.nover 60 | mv $@.nover $@ 61 | #remove section header 62 | ./Section-Header-Stripper/section-stripper.py $@ 63 | 64 | #clear out useless bits 65 | sed -i 's/_edata/\x00\x00\x00\x00\x00\x00/g' $@; 66 | sed -i 's/__bss_start/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/g' $@; 67 | sed -i 's/_end/\x00\x00\x00\x00/g' $@; 68 | sed -i 's/GLIBC_2\.2\.5/\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00/g' $@; 69 | 70 | chmod +x $@ 71 | 72 | %.xz : % Makefile 73 | -rm $@ 74 | lzma --format=lzma -9 --extreme --lzma1=preset=9,lc=0,lp=0,pb=0,nice=40,depth=32,dict=16384 --keep --stdout $< > $@ 75 | 76 | %.packed : %.xz packer Makefile 77 | cat ./vondehi/vondehi $< > $@ 78 | chmod +x $@ 79 | wc -c $@ 80 | 81 | clean : 82 | -rm *.elf shader.h gtk-opengl xlib-opengl sdl2-opengl 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Linux-OpenGL-Examples 2 | 3 | Here are examples of rendering a shader full screen on linux. All of these examples do it in less than 2 kilobytes thanks to vondehi and copious amounts of ELF stripping. 4 | 5 | There are three examples, each using a different library to open a window and get an opengl context. 6 | 7 | ## xlib-opengl - 1492 bytes 8 | 9 | Vanilla xlib is the largest of the bunch and the most brittle. It is highly not recommended to use xlib in a demo unless you cannot assume these other libraries will be on the system. (note, unlike all the other programs that close with the window manager's quit key combination, this program must be closed with ESC.) 10 | 11 | ## gtk-opengl - 1382 bytes 12 | 13 | GTK is a step up from xlib, being both smaller and more robust. If the compo you are entering doesn't allow using SDL2, GTK is an ok alternative. Before switching to GCC 8.3.0, this was 100 bytes smaller than it is now. I am not sure why it is larger, but this likely means it can be sizecoded/stripped further. 14 | 15 | ## sdl2-opengl - 996 bytes 16 | 17 | Using SDL2 will give you very small binaries. Use SDL2 whenever you can, as it also has a few other useful subsystems at minimal cost (for example, audio.) 18 | 19 | -------------------------------------------------------------------------------- /gtk-opengl.c: -------------------------------------------------------------------------------- 1 | #define GL_GLEXT_PROTOTYPES why 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #include "shader.h" 17 | static char* vshader = "#version 450\nvec2 y=vec2(1.,-1);vec4 x[4]={y.yyxx,y.xyxx,y.yxxx,y.xxxx};void main(){gl_Position=x[gl_VertexID];}"; 18 | 19 | #define CANVAS_WIDTH 1920 20 | #define CANVAS_HEIGHT 1080 21 | // #define DEBUG 22 | 23 | GLuint vao; 24 | GLuint p; 25 | 26 | static gboolean 27 | on_render (GtkGLArea *glarea, GdkGLContext *context) 28 | { 29 | glUseProgram(p); 30 | glBindVertexArray(vao); 31 | glVertexAttrib1f(0, 0); 32 | glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); 33 | 34 | return TRUE; 35 | } 36 | 37 | static void on_realize(GtkGLArea *glarea) 38 | { 39 | gtk_gl_area_make_current(glarea); 40 | 41 | // compile shader 42 | GLuint f = glCreateShader(GL_FRAGMENT_SHADER); 43 | glShaderSource(f, 1, &shader_frag, NULL); 44 | glCompileShader(f); 45 | 46 | #ifdef DEBUG 47 | GLint isCompiled = 0; 48 | glGetShaderiv(f, GL_COMPILE_STATUS, &isCompiled); 49 | if(isCompiled == GL_FALSE) { 50 | GLint maxLength = 0; 51 | glGetShaderiv(f, GL_INFO_LOG_LENGTH, &maxLength); 52 | 53 | char* error = malloc(maxLength); 54 | glGetShaderInfoLog(f, maxLength, &maxLength, error); 55 | printf("%s\n", error); 56 | 57 | exit(-10); 58 | } 59 | #endif 60 | 61 | GLuint v = glCreateShader(GL_VERTEX_SHADER); 62 | glShaderSource(v, 1, &vshader, NULL); 63 | glCompileShader(v); 64 | 65 | #ifdef DEBUG 66 | GLint isCompiled2 = 0; 67 | glGetShaderiv(v, GL_COMPILE_STATUS, &isCompiled2); 68 | if(isCompiled2 == GL_FALSE) { 69 | GLint maxLength = 0; 70 | glGetShaderiv(v, GL_INFO_LOG_LENGTH, &maxLength); 71 | 72 | char* error = malloc(maxLength); 73 | glGetShaderInfoLog(v, maxLength, &maxLength, error); 74 | printf("%s\n", error); 75 | 76 | exit(-10); 77 | } 78 | #endif 79 | 80 | // link shader 81 | p = glCreateProgram(); 82 | glAttachShader(p,v); 83 | glAttachShader(p,f); 84 | glLinkProgram(p); 85 | 86 | #ifdef DEBUG 87 | GLint isLinked = 0; 88 | glGetProgramiv(p, GL_LINK_STATUS, (int *)&isLinked); 89 | if (isLinked == GL_FALSE) { 90 | GLint maxLength = 0; 91 | glGetProgramiv(p, GL_INFO_LOG_LENGTH, &maxLength); 92 | 93 | char* error = malloc(maxLength); 94 | glGetProgramInfoLog(p, maxLength, &maxLength,error); 95 | printf("%s\n", error); 96 | 97 | exit(-10); 98 | } 99 | #endif 100 | 101 | glGenVertexArrays(1, &vao); 102 | 103 | // if you want to continuously render the shader once per frame 104 | // GdkGLContext *context = gtk_gl_area_get_context(glarea); 105 | // GdkWindow *glwindow = gdk_gl_context_get_window(context); 106 | // GdkFrameClock *frame_clock = gdk_window_get_frame_clock(glwindow); 107 | 108 | // // Connect update signal: 109 | // g_signal_connect_swapped(frame_clock, "update", G_CALLBACK(gtk_gl_area_queue_render), glarea); 110 | 111 | // // Start updating: 112 | // gdk_frame_clock_begin_updating(frame_clock); 113 | } 114 | 115 | void _start() { 116 | asm volatile("sub $8, %rsp\n"); 117 | 118 | typedef void (*voidWithOneParam)(int*); 119 | voidWithOneParam gtk_init_one_param = (voidWithOneParam)gtk_init; 120 | (*gtk_init_one_param)(NULL); 121 | 122 | GtkWidget *win = gtk_window_new (GTK_WINDOW_TOPLEVEL); 123 | GtkWidget *glarea = gtk_gl_area_new(); 124 | gtk_container_add(GTK_CONTAINER(win), glarea); 125 | 126 | g_signal_connect(win, "destroy", gtk_main_quit, NULL); 127 | g_signal_connect(glarea, "realize", G_CALLBACK(on_realize), NULL); 128 | g_signal_connect(glarea, "render", G_CALLBACK(on_render), NULL); 129 | 130 | gtk_widget_show_all (win); 131 | 132 | gtk_window_fullscreen((GtkWindow*)win); 133 | GdkWindow* window = gtk_widget_get_window(win); 134 | GdkCursor* Cursor = gdk_cursor_new(GDK_BLANK_CURSOR); 135 | gdk_window_set_cursor(window, Cursor); 136 | 137 | gtk_main(); 138 | 139 | asm volatile(".intel_syntax noprefix"); 140 | asm volatile("push 231"); //exit_group 141 | asm volatile("pop rax"); 142 | // asm volatile("xor edi, edi"); 143 | asm volatile("syscall"); 144 | asm volatile(".att_syntax prefix"); 145 | __builtin_unreachable(); 146 | // return 0; 147 | } -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /index.html.inc: -------------------------------------------------------------------------------- 1 | 0x3c, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x2a, 0x7b, 0x6d, 0x61, 0x72, 2 | 0x67, 0x69, 0x6e, 0x3a, 0x30, 0x70, 0x78, 0x3b, 0x70, 0x61, 0x64, 0x64, 3 | 0x69, 0x6e, 0x67, 0x3a, 0x30, 0x70, 0x78, 0x3b, 0x6f, 0x76, 0x65, 0x72, 4 | 0x66, 0x6c, 0x6f, 0x77, 0x3a, 0x68, 0x69, 0x64, 0x64, 0x65, 0x6e, 0x3b, 5 | 0x7d, 0x3c, 0x2f, 0x73, 0x74, 0x79, 0x6c, 0x65, 0x3e, 0x0a, 0x3c, 0x63, 6 | 0x61, 0x6e, 0x76, 0x61, 0x73, 0x20, 0x69, 0x64, 0x3d, 0x22, 0x77, 0x65, 7 | 0x62, 0x67, 0x6c, 0x22, 0x20, 0x77, 0x69, 0x64, 0x74, 0x68, 0x3d, 0x22, 8 | 0x31, 0x39, 0x32, 0x30, 0x22, 0x20, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 9 | 0x3d, 0x22, 0x31, 0x30, 0x38, 0x30, 0x22, 0x3e, 0x3c, 0x2f, 0x63, 0x61, 10 | 0x6e, 0x76, 0x61, 0x73, 0x3e, 0x0a, 0x3c, 0x73, 0x63, 0x72, 0x69, 0x70, 11 | 0x74, 0x3e, 0x0a, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 12 | 0x73, 0x50, 0x28, 0x72, 0x2c, 0x65, 0x2c, 0x74, 0x29, 0x7b, 0x76, 0x61, 13 | 0x72, 0x20, 0x61, 0x3d, 0x72, 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 14 | 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x28, 0x29, 0x2c, 0x6f, 0x3d, 15 | 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 0x74, 16 | 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x6f, 0x3d, 0x72, 0x2e, 0x63, 0x72, 17 | 0x65, 0x61, 0x74, 0x65, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x28, 0x22, 18 | 0x76, 0x65, 0x72, 0x74, 0x65, 0x78, 0x22, 0x3d, 0x3d, 0x65, 0x3f, 0x72, 19 | 0x2e, 0x56, 0x45, 0x52, 0x54, 0x45, 0x58, 0x5f, 0x53, 0x48, 0x41, 0x44, 20 | 0x45, 0x52, 0x3a, 0x72, 0x2e, 0x46, 0x52, 0x41, 0x47, 0x4d, 0x45, 0x4e, 21 | 0x54, 0x5f, 0x53, 0x48, 0x41, 0x44, 0x45, 0x52, 0x29, 0x3b, 0x72, 0x2e, 22 | 0x73, 0x68, 0x61, 0x64, 0x65, 0x72, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 23 | 0x28, 0x6f, 0x2c, 0x74, 0x29, 0x2c, 0x72, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 24 | 0x69, 0x6c, 0x65, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x28, 0x6f, 0x29, 25 | 0x2c, 0x72, 0x2e, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68, 0x53, 0x68, 0x61, 26 | 0x64, 0x65, 0x72, 0x28, 0x61, 0x2c, 0x6f, 0x29, 0x7d, 0x3b, 0x72, 0x65, 27 | 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6f, 0x28, 0x22, 0x76, 0x65, 0x72, 0x74, 28 | 0x65, 0x78, 0x22, 0x2c, 0x65, 0x29, 0x2c, 0x6f, 0x28, 0x22, 0x66, 0x72, 29 | 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x2c, 0x74, 0x29, 0x2c, 0x72, 30 | 0x2e, 0x6c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 31 | 0x28, 0x61, 0x29, 0x2c, 0x61, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 32 | 0x6f, 0x6e, 0x20, 0x61, 0x74, 0x73, 0x66, 0x28, 0x72, 0x2c, 0x65, 0x2c, 33 | 0x74, 0x2c, 0x61, 0x2c, 0x6f, 0x29, 0x7b, 0x72, 0x2e, 0x62, 0x69, 0x6e, 34 | 0x64, 0x42, 0x75, 0x66, 0x66, 0x65, 0x72, 0x28, 0x72, 0x2e, 0x41, 0x52, 35 | 0x52, 0x41, 0x59, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x2c, 0x72, 36 | 0x2e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x42, 0x75, 0x66, 0x66, 0x65, 37 | 0x72, 0x28, 0x29, 0x29, 0x2c, 0x72, 0x2e, 0x62, 0x75, 0x66, 0x66, 0x65, 38 | 0x72, 0x44, 0x61, 0x74, 0x61, 0x28, 0x72, 0x2e, 0x41, 0x52, 0x52, 0x41, 39 | 0x59, 0x5f, 0x42, 0x55, 0x46, 0x46, 0x45, 0x52, 0x2c, 0x6e, 0x65, 0x77, 40 | 0x20, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x33, 0x32, 0x41, 0x72, 0x72, 0x61, 41 | 0x79, 0x28, 0x6f, 0x29, 0x2c, 0x72, 0x2e, 0x53, 0x54, 0x41, 0x54, 0x49, 42 | 0x43, 0x5f, 0x44, 0x52, 0x41, 0x57, 0x29, 0x3b, 0x76, 0x61, 0x72, 0x20, 43 | 0x69, 0x3d, 0x72, 0x2e, 0x67, 0x65, 0x74, 0x41, 0x74, 0x74, 0x72, 0x69, 44 | 0x62, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x28, 0x65, 0x2c, 45 | 0x74, 0x29, 0x3b, 0x72, 0x2e, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x56, 46 | 0x65, 0x72, 0x74, 0x65, 0x78, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x41, 47 | 0x72, 0x72, 0x61, 0x79, 0x28, 0x69, 0x29, 0x2c, 0x72, 0x2e, 0x76, 0x65, 48 | 0x72, 0x74, 0x65, 0x78, 0x41, 0x74, 0x74, 0x72, 0x69, 0x62, 0x50, 0x6f, 49 | 0x69, 0x6e, 0x74, 0x65, 0x72, 0x28, 0x69, 0x2c, 0x61, 0x2c, 0x72, 0x2e, 50 | 0x46, 0x4c, 0x4f, 0x41, 0x54, 0x2c, 0x21, 0x31, 0x2c, 0x30, 0x2c, 0x30, 51 | 0x29, 0x7d, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x64, 52 | 0x72, 0x28, 0x29, 0x7b, 0x76, 0x61, 0x72, 0x20, 0x72, 0x3d, 0x64, 0x6f, 53 | 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74, 0x2e, 0x67, 0x65, 0x74, 0x45, 0x6c, 54 | 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x79, 0x49, 0x64, 0x28, 0x22, 0x77, 55 | 0x65, 0x62, 0x67, 0x6c, 0x22, 0x29, 0x2e, 0x67, 0x65, 0x74, 0x43, 0x6f, 56 | 0x6e, 0x74, 0x65, 0x78, 0x74, 0x28, 0x22, 0x77, 0x65, 0x62, 0x67, 0x6c, 57 | 0x22, 0x29, 0x2c, 0x65, 0x3d, 0x73, 0x50, 0x28, 0x72, 0x2c, 0x22, 0x61, 58 | 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 59 | 0x32, 0x20, 0x70, 0x73, 0x3b, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 60 | 0x69, 0x6e, 0x28, 0x29, 0x7b, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 61 | 0x74, 0x69, 0x6f, 0x6e, 0x3d, 0x76, 0x65, 0x63, 0x34, 0x28, 0x70, 0x73, 62 | 0x2c, 0x30, 0x2e, 0x2c, 0x31, 0x2e, 0x29, 0x3b, 0x7d, 0x22, 0x2c, 0x22, 63 | 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x28, 0x29, 0x7b, 64 | 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 0x67, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 65 | 0x3d, 0x76, 0x65, 0x63, 0x34, 0x28, 0x67, 0x6c, 0x5f, 0x46, 0x72, 0x61, 66 | 0x67, 0x43, 0x6f, 0x6f, 0x72, 0x64, 0x2e, 0x78, 0x2f, 0x31, 0x39, 0x32, 67 | 0x30, 0x2e, 0x2c, 0x30, 0x2e, 0x35, 0x2c, 0x31, 0x2e, 0x2c, 0x31, 0x2e, 68 | 0x29, 0x3b, 0x7d, 0x22, 0x29, 0x3b, 0x72, 0x2e, 0x75, 0x73, 0x65, 0x50, 69 | 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x28, 0x65, 0x29, 0x2c, 0x61, 0x74, 70 | 0x73, 0x66, 0x28, 0x72, 0x2c, 0x65, 0x2c, 0x22, 0x70, 0x73, 0x22, 0x2c, 71 | 0x32, 0x2c, 0x5b, 0x2d, 0x31, 0x2c, 0x31, 0x2c, 0x31, 0x2c, 0x31, 0x2c, 72 | 0x2d, 0x31, 0x2c, 0x2d, 0x31, 0x2c, 0x31, 0x2c, 0x2d, 0x31, 0x5d, 0x29, 73 | 0x2c, 0x72, 0x2e, 0x64, 0x72, 0x61, 0x77, 0x41, 0x72, 0x72, 0x61, 0x79, 74 | 0x73, 0x28, 0x72, 0x2e, 0x54, 0x52, 0x49, 0x41, 0x4e, 0x47, 0x4c, 0x45, 75 | 0x5f, 0x53, 0x54, 0x52, 0x49, 0x50, 0x2c, 0x30, 0x2c, 0x34, 0x29, 0x7d, 76 | 0x73, 0x65, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x28, 0x64, 77 | 0x72, 0x2c, 0x31, 0x30, 0x29, 0x2c, 0x64, 0x72, 0x28, 0x29, 0x3b, 0x0a, 78 | 0x3c, 0x2f, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x3e 79 | , 0 80 | -------------------------------------------------------------------------------- /sdl2-opengl.c: -------------------------------------------------------------------------------- 1 | #define GL_GLEXT_PROTOTYPES 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include "shader.h" 16 | 17 | #define CANVAS_WIDTH 1920 18 | #define CANVAS_HEIGHT 1080 19 | // #define KEY_HANDLING 20 | // #define DEBUG 21 | 22 | static void on_render () 23 | { 24 | glRecti(-1,-1,1,1); 25 | } 26 | 27 | static void on_realize() 28 | { 29 | // compile shader 30 | GLuint f = glCreateShader(GL_FRAGMENT_SHADER); 31 | glShaderSource(f, 1, &shader_frag, NULL); 32 | glCompileShader(f); 33 | 34 | #ifdef DEBUG 35 | GLint isCompiled = 0; 36 | glGetShaderiv(f, GL_COMPILE_STATUS, &isCompiled); 37 | if(isCompiled == GL_FALSE) { 38 | GLint maxLength = 0; 39 | glGetShaderiv(f, GL_INFO_LOG_LENGTH, &maxLength); 40 | 41 | char* error = malloc(maxLength); 42 | glGetShaderInfoLog(f, maxLength, &maxLength, error); 43 | printf("%s\n", error); 44 | 45 | exit(-10); 46 | } 47 | #endif 48 | 49 | // link shader 50 | GLuint p = glCreateProgram(); 51 | glAttachShader(p,f); 52 | glLinkProgram(p); 53 | 54 | #ifdef DEBUG 55 | GLint isLinked = 0; 56 | glGetProgramiv(p, GL_LINK_STATUS, (int *)&isLinked); 57 | if (isLinked == GL_FALSE) { 58 | GLint maxLength = 0; 59 | glGetProgramiv(p, GL_INFO_LOG_LENGTH, &maxLength); 60 | 61 | char* error = malloc(maxLength); 62 | glGetProgramInfoLog(p, maxLength, &maxLength,error); 63 | printf("%s\n", error); 64 | 65 | exit(-10); 66 | } 67 | #endif 68 | 69 | glUseProgram(p); 70 | } 71 | 72 | void _start() { 73 | asm volatile("sub $8, %rsp\n"); 74 | 75 | SDL_Init(SDL_INIT_VIDEO | SDL_INIT_EVENTS); 76 | SDL_Window* mainwindow = SDL_CreateWindow( 77 | "", 78 | 0, 79 | 0, 80 | CANVAS_WIDTH, 81 | CANVAS_HEIGHT, 82 | SDL_WINDOW_OPENGL | SDL_WINDOW_FULLSCREEN 83 | ); 84 | 85 | SDL_GL_CreateContext(mainwindow); 86 | SDL_ShowCursor(false); 87 | on_realize(); 88 | 89 | while (true) { 90 | SDL_Event Event; 91 | while (SDL_PollEvent(&Event)) { 92 | if (Event.type == SDL_QUIT 93 | #if defined(KEY_HANDLING) 94 | || (Event.type == SDL_KEYDOWN && Event.key.keysym.sym == SDLK_ESCAPE) 95 | #endif 96 | ) { 97 | asm volatile(".intel_syntax noprefix"); 98 | asm volatile("push 231"); //exit_group 99 | asm volatile("pop rax"); 100 | asm volatile("xor edi, edi"); 101 | asm volatile("syscall"); 102 | asm volatile(".att_syntax prefix"); 103 | __builtin_unreachable(); 104 | } 105 | if (Event.type == SDL_WINDOWEVENT && Event.window.event == SDL_WINDOWEVENT_EXPOSED) { 106 | on_render(); 107 | SDL_GL_SwapWindow(mainwindow); 108 | } 109 | } 110 | } 111 | __builtin_unreachable(); 112 | } 113 | -------------------------------------------------------------------------------- /shader.frag: -------------------------------------------------------------------------------- 1 | #version 450 2 | 3 | out vec4 fragColor; 4 | 5 | void main() 6 | { 7 | // Normalized pixel coordinates (from -1 to 1) 8 | vec2 iResolution = vec2(1920.0, 1080.0); 9 | vec2 uv = (gl_FragCoord.xy/iResolution.xy)*2.0 - vec2(1.0,1.0); 10 | uv.y *= iResolution.y/iResolution.x; 11 | 12 | fragColor = abs(uv.yxyx); 13 | } -------------------------------------------------------------------------------- /shader_minifier.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/blackle/Linux-OpenGL-Examples/6ecfc7a26e4d11d9d4837a0e99cfe91b23bbc5bf/shader_minifier.exe -------------------------------------------------------------------------------- /xlib-opengl.c: -------------------------------------------------------------------------------- 1 | #define GL_GLEXT_PROTOTYPES why 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include "shader.h" 16 | 17 | #define CANVAS_WIDTH 1920 18 | #define CANVAS_HEIGHT 1080 19 | // #define DEBUG true 20 | 21 | static unsigned char fbdata[4 * CANVAS_HEIGHT * CANVAS_WIDTH]; 22 | 23 | void _start() { 24 | asm volatile("sub $8, %rsp\n"); 25 | 26 | Display* dpy = XOpenDisplay(NULL); 27 | Window root = DefaultRootWindow(dpy); 28 | 29 | static GLint att[] = { GLX_RGBA, None }; 30 | XVisualInfo* vi = glXChooseVisual(dpy, 0, att); 31 | 32 | //I really hate this and I wish this call was unneeded. it feels useless 33 | Colormap cmap = XCreateColormap(dpy, root, vi->visual, AllocNone); 34 | 35 | //hide cursor 36 | XColor xcolor; 37 | Pixmap csr= XCreatePixmap(dpy,root,1,1,1); 38 | Cursor cursor= XCreatePixmapCursor(dpy,csr,csr,&xcolor,&xcolor,1,1); 39 | 40 | //this enables things like events, fullscreen, and sets the invisible cursor 41 | static XSetWindowAttributes swa = { .override_redirect = 1, .event_mask = ExposureMask | KeyPressMask }; 42 | swa.colormap = cmap; 43 | swa.cursor = cursor; 44 | Window win = XCreateWindow(dpy, root, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask | CWOverrideRedirect | CWCursor, &swa); 45 | 46 | //this actually opens the window 47 | XMapWindow(dpy, win); 48 | 49 | //now we can do opengl calls!!!! 50 | GLXContext glc = glXCreateContext(dpy, vi, NULL, 1); 51 | 52 | #ifdef DEBUG 53 | if (glc == NULL) { 54 | return; 55 | } 56 | #endif 57 | 58 | glXMakeCurrent(dpy, win, glc); 59 | 60 | glClear(GL_COLOR_BUFFER_BIT); 61 | 62 | //oh yeah grab the keyboard 63 | XGrabKeyboard(dpy, win, true, GrabModeAsync, GrabModeAsync, CurrentTime); 64 | 65 | //create a floating point backing texture for a framebuffer 66 | GLuint textureA; 67 | glEnable(GL_TEXTURE_2D); 68 | glGenTextures(1, &textureA); 69 | glBindTexture(GL_TEXTURE_2D, textureA); 70 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 71 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 72 | glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, CANVAS_WIDTH, CANVAS_HEIGHT, 0, GL_BGRA, GL_UNSIGNED_BYTE, fbdata); 73 | 74 | //create a framebuffer we can render everything to 75 | GLuint fboA; 76 | glGenFramebuffers(1, &fboA); 77 | glBindFramebuffer(GL_FRAMEBUFFER, fboA); 78 | glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 79 | GL_TEXTURE_2D, textureA, 0); 80 | 81 | // compile shader 82 | GLuint f = glCreateShader(GL_FRAGMENT_SHADER); 83 | glShaderSource(f, 1, &shader_frag, NULL); 84 | glCompileShader(f); 85 | 86 | #ifdef DEBUG 87 | GLint isCompiled = 0; 88 | glGetShaderiv(f, GL_COMPILE_STATUS, &isCompiled); 89 | if(isCompiled == GL_FALSE) { 90 | GLint maxLength = 0; 91 | glGetShaderiv(f, GL_INFO_LOG_LENGTH, &maxLength); 92 | 93 | char* error = malloc(maxLength); 94 | glGetShaderInfoLog(f, maxLength, &maxLength, error); 95 | printf("%s\n", error); 96 | 97 | exit(-10); 98 | } 99 | #endif 100 | 101 | // link shader 102 | GLuint p = glCreateProgram(); 103 | glAttachShader(p,f); 104 | glLinkProgram(p); 105 | 106 | #ifdef DEBUG 107 | GLint isLinked = 0; 108 | glGetProgramiv(p, GL_LINK_STATUS, (int *)&isLinked); 109 | if (isLinked == GL_FALSE) { 110 | GLint maxLength = 0; 111 | glGetProgramiv(p, GL_INFO_LOG_LENGTH, &maxLength); 112 | 113 | char* error = malloc(maxLength); 114 | glGetProgramInfoLog(p, maxLength, &maxLength,error); 115 | printf("%s\n", error); 116 | 117 | exit(-10); 118 | } 119 | #endif 120 | 121 | glUseProgram(p); 122 | 123 | //switch to using our framebuffer 124 | glBindFramebuffer(GL_FRAMEBUFFER, fboA); 125 | 126 | // glFinish(); 127 | glRecti(-1,-1,1,1); 128 | 129 | //blit our framebuffer to the screen 130 | glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 131 | glBindFramebuffer(GL_READ_FRAMEBUFFER, fboA); 132 | 133 | glBlitFramebuffer(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, 0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, GL_COLOR_BUFFER_BIT, GL_NEAREST); 134 | 135 | static XEvent xev; 136 | while(1) { 137 | XNextEvent(dpy, &xev); 138 | 139 | //wait for escape key, then exit without glib :3 140 | if(xev.type == KeyPress && xev.xkey.keycode == 0x09) { 141 | //blackle mori no likey AT&T 142 | asm volatile(".intel_syntax noprefix"); 143 | asm volatile("push 60"); 144 | asm volatile("pop rax"); 145 | asm volatile("xor edi, edi"); 146 | asm volatile("syscall"); 147 | asm volatile(".att_syntax prefix"); 148 | __builtin_unreachable(); 149 | } 150 | } 151 | } 152 | --------------------------------------------------------------------------------