Last active
January 7, 2021 14:35
-
-
Save LAK132/2a427b8939d42aabf3750fe2baeb3fa2 to your computer and use it in GitHub Desktop.
Makefile but it uses Tiny C Compiler to open an Xlib/GLX window
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#if 0 | |
ifneq ($(shell grep -a -h -i microsoft /proc/version),) | |
# // For use on Windows (WSL) with cygwinX | |
# // Requires xinit, xauth and xhost probably | |
# // Start the X11 server with `path\to\cygwin64\bin\run.exe --quote /usr/bin/bash.exe -l -c "cd; exec /usr/bin/startxwin -- +iglx -listen tcp"` | |
# // If you get "Authorization required, but no authorization protocol specified" | |
# // then try running `DISPLAY=:0.0 xhost +` in the cygwin terminal after | |
# // starting the X11 server. | |
DISPLAY = "`cat /etc/resolv.conf | grep nameserver | awk '{ print $$2 }'`:0.0" | |
LIBGLARGS = LIBGL_ALWAYS_INDIRECT=1 LIBGL_ALWAYS_SOFTWARE=1 | |
endif | |
.PHONY: run | |
run: | |
$(shell $(LIBGLARGS) tcc -run -lX11 -lGL -lGLU Makefile ) | |
ifeq (0, 1) | |
#endif | |
#include "GL/gl.h" | |
#include "GL/glu.h" | |
#include "GL/glx.h" | |
#include "X11/Xlib.h" | |
#include "stdio.h" | |
#include "string.h" | |
int main(int argc, const char *argv[]) | |
{ | |
/* | |
* Open a connection to the X server for a display. | |
* On POSIX conforming system, NULL means use the DISPLAY | |
* environment variable. | |
* Otherwise the display name should take the form | |
* "hostname:display_number.screen_number". | |
*/ | |
const char *display_name = argc > 1 ? argv[1] : NULL; /* ":0"; */ | |
if (display_name) printf("Connecting to display %s\n", display_name); | |
Display *display = XOpenDisplay(display_name); | |
/* XOpenDisplay returns NULL on failure. */ | |
if (display == NULL) | |
{ | |
fprintf(stderr, "Failed to open Xlib display\n"); | |
return 1; | |
} | |
int screen = DefaultScreen(display); | |
int window_width = 200; | |
int window_height = 200; | |
Window root = RootWindow(display, screen); | |
/* Set up an OpenGL context */ | |
GLint attributes[] = {GLX_RGBA, GLX_DEPTH_SIZE, 24, None}; | |
XVisualInfo *visual_info = glXChooseVisual(display, 0, attributes); | |
if (visual_info == NULL) | |
{ | |
fprintf(stderr, "Failed to get visual info\n"); | |
return 1; | |
} | |
XSetWindowAttributes window_attributes; | |
window_attributes.colormap = | |
XCreateColormap(display, root, visual_info->visual, AllocNone); | |
/* Select the kind of events we are interestedn in. */ | |
window_attributes.event_mask = ExposureMask | KeyPressMask; | |
/* Create a window. */ | |
Window window = XCreateWindow(display, /* display */ | |
root, /* parent */ | |
10, /* x */ | |
10, /* y */ | |
window_width, /* width */ | |
window_height, /* height */ | |
0, /* border width */ | |
visual_info->depth, /* depth */ | |
InputOutput, /* class */ | |
visual_info->visual, /* visual */ | |
CWColormap | CWEventMask, /* value mask */ | |
&window_attributes /* attributes */ | |
); | |
/* Map (show) the window. */ | |
XMapWindow(display, window); | |
/* | |
* When the user attempts to close the window via the (X) | |
* button drawn by the system's window manager the program | |
* will recieve a ClientMessage event with the WM_DELETE_WINDOW | |
* atom. | |
*/ | |
Atom wm_delete_window = XInternAtom(display, /* display */ | |
"WM_DELETE_WINDOW", /* atom name */ | |
0 /* only if exists */ | |
); | |
XSetWMProtocols(display, /* display */ | |
window, /* window */ | |
&wm_delete_window, /* protocols */ | |
1 /* count */ | |
); | |
/* Message to draw in the window. */ | |
const char *title = "X11/Xlib window example"; | |
/* Set the window title. */ | |
XStoreName(display, window, title); | |
GLXContext opengl_context = | |
glXCreateContext(display, visual_info, NULL, GL_TRUE); | |
if (opengl_context == NULL) | |
{ | |
fprintf(stderr, "Failed to create OpenGL context\n"); | |
return 1; | |
} | |
if (!glXMakeCurrent(display, window, opengl_context)) | |
{ | |
fprintf(stderr, "Failed to make OpenGL context current\n"); | |
return 1; | |
} | |
glEnable(GL_DEPTH_TEST); | |
/* Main event loop. */ | |
for (int running = 1; running;) | |
{ | |
XEvent event; | |
/* Get the next window event. */ | |
XNextEvent(display, &event); | |
switch (event.type) | |
{ | |
/* Exit on key press */ | |
case KeyPress: | |
{ | |
running = 0; | |
} | |
break; | |
/* | |
* Exit when the user presses the (X) button on the | |
* window. | |
*/ | |
case ClientMessage: | |
{ | |
if ((Atom)event.xclient.data.l[0] == wm_delete_window) running = 0; | |
} | |
break; | |
default: break; | |
} | |
glClearColor(1.0, 1.0, 1.0, 1.0); | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
glMatrixMode(GL_PROJECTION); | |
glLoadIdentity(); | |
glOrtho(-1.0, 1.0, -1.0, 1.0, 1.0, 20.0); | |
glMatrixMode(GL_MODELVIEW); | |
glLoadIdentity(); | |
gluLookAt(0.0, 0.0, 10.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); | |
glBegin(GL_QUADS); | |
glColor3f(1.0, 0.0, 0.0); | |
glVertex3f(-0.75, -0.75, 0.0); | |
glColor3f(0.0, 1.0, 0.0); | |
glVertex3f(0.75, -0.75, 0.0); | |
glColor3f(0.0, 0.0, 1.0); | |
glVertex3f(0.75, 0.75, 0.0); | |
glColor3f(1.0, 1.0, 0.0); | |
glVertex3f(-0.75, 0.75, 0.0); | |
glEnd(); | |
glFlush(); | |
} | |
glXDestroyContext(display, opengl_context); | |
/* Unmap (hide) the window. */ | |
XUnmapWindow(display, window); | |
/* Destroy the window. */ | |
XDestroyWindow(display, window); | |
/* Close the connection to the X server for display. */ | |
XCloseDisplay(display); | |
} | |
#define endif | |
endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment