commit 6edbbe11040624e99fdec37abbc8784b4f674241
Author: bsandro <email@bsandro.tech>
Date: Mon, 6 Oct 2025 14:45:17 +0300
init
Diffstat:
| A | Makefile | | | 12 | ++++++++++++ |
| A | main1.c | | | 156 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | main2.c | | | 162 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 330 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,12 @@
+all:
+ ${CC} main1.c -std=c99 -Wpedantic -Os -s -fomit-frame-pointer -ffast-math -fno-stack-protector -march=native -fwrapv -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables -fno-unwind-tables -fmerge-all-constants -fno-ident -lGL -lGLU -lX11 -Wl,--gc-sections -o test1
+
+min: all
+ strip -S --strip-unneeded --remove-section=.note.gnu.gold-version --remove-section=.comment --remove-section=.note --remove-section=.note.gnu.build-id --remove-section=.note.ABI-tag ./test1
+ upx -9 ./test1
+
+clean:
+ rm ./test1
+
+run: min
+ ./test1
diff --git a/main1.c b/main1.c
@@ -0,0 +1,156 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#define GL_GLEXT_PROTOTYPES 1
+#include <GL/gl.h>
+#include <GL/glx.h>
+#include <GL/glu.h>
+
+Display *dpy;
+Window root;
+GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
+XVisualInfo *vi;
+XSetWindowAttributes swa;
+Window win;
+XWindowAttributes gwa;
+XEvent xev;
+
+static const GLchar *vertexSrc = " \n\
+#version 150 core \n\
+in vec3 position; \n\
+void main() { \n\
+ gl_Position = vec4(position, 1.0); \n\
+} \n\
+";
+
+static const GLchar *fragmentSrc = " \n\
+#version 150 core \n\
+out vec4 outColor; \n\
+void main() { \n\
+ outColor = vec4(0.7, 0.5, 0.3, 1.0);\n\
+} \n\
+";
+
+static GLuint mkShader(GLenum type, const GLchar *src) {
+ GLuint shader = glCreateShader(type);
+ glShaderSource(shader, 1, &src, NULL);
+ glCompileShader(shader);
+ GLint ok = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &ok);
+ if (!ok) {
+ static char buf[512] = {0};
+ glGetShaderInfoLog(shader, sizeof(buf)-1, NULL, buf);
+ fprintf(stderr, "Shader %d compile error: %s\n", (int)type, buf);
+ }
+ return shader;
+}
+
+static GLuint linkProgram(GLuint vertex, GLuint fragment) {
+ GLuint shaderProgram = glCreateProgram();
+ glAttachShader(shaderProgram, vertex);
+ glAttachShader(shaderProgram, fragment);
+ glBindAttribLocation(shaderProgram, 0, "position");
+ glBindFragDataLocation(shaderProgram, 0, "outColor");
+ glLinkProgram(shaderProgram);
+ return shaderProgram;
+}
+
+void DrawThing() {
+ glClearColor(0.1f, 0.1f, 0.15f, 1.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+
+ /*glBegin(GL_TRIANGLES);
+ // Vertex data
+ glColor3f(1.0f, 0.0f, 0.0f);
+ glVertex3f(-0.3f, 0.0f, 0.0f);
+ glColor3f(0.0f, 1.0f, 0.0f);
+ glVertex3f(0.3f, 0.1f, 0.0f);
+ glColor3f(1.0f, 0.0f, 1.0f);
+ glVertex3f(0.0f, 0.8f, 0.0f);
+ glEnd();
+
+ glBegin(GL_POLYGON);
+ glColor3f(0.8f, 0.0f, 0.0f);
+ glVertex3f(0.5f, 0.5f, 0.5f);
+ glVertex3f(0.1f, 0.1f, 0.1f);
+ glVertex3f(-0.1f, -0.1f, 0.1f);
+ glVertex3f(0.4f, 0.0f, 0.0f);
+ glVertex3f(-0.4f, 0.0f, 0.3f);
+ glEnd();*/
+
+ GLuint vao;
+ glGenVertexArrays(1, &vao);
+ glBindVertexArray(vao);
+
+ GLfloat vertices[] = {
+ 0.0f, 0.0f, 0.0f,
+ 0.4f, 0.0f, 0.0f,
+ 0.0f, 0.4f, 0.0f
+ };
+
+ GLuint vbo;
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);
+
+ GLuint vertex = mkShader(GL_VERTEX_SHADER, vertexSrc);
+ GLuint fragment = mkShader(GL_FRAGMENT_SHADER, fragmentSrc);
+ GLuint shaderPrg = linkProgram(vertex, fragment);
+ glUseProgram(shaderPrg);
+
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid *)0);
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ glDisableVertexAttribArray(0);
+ glUseProgram(0);
+}
+
+int main(int argc, char *argv[]) {
+ dpy = XOpenDisplay(NULL);
+
+ if (dpy == NULL) {
+ printf("\n\tcannot connect to X server\n\n");
+ exit(0);
+ }
+
+ root = DefaultRootWindow(dpy);
+ vi = glXChooseVisual(dpy, 0, att);
+
+ if (vi == NULL) {
+ printf("\n\tno appropriate visual found\n\n");
+ exit(0);
+ } else {
+ printf("\n\tvisual %p selected\n", (void *)vi->visualid); /* %p creates hexadecimal output like in glxinfo */
+ }
+
+ Colormap cmap = XCreateColormap(dpy, root, vi->visual, AllocNone);
+ swa.colormap = cmap;
+ swa.event_mask = ExposureMask | KeyPressMask;
+ win = XCreateWindow(dpy, root, 0, 0, 500, 500, 0, vi->depth, InputOutput, vi->visual, CWColormap | CWEventMask, &swa);
+ XMapWindow(dpy, win);
+ XStoreName(dpy, win, "OPENGL");
+ GLXContext ctx = glXCreateContext(dpy, vi, NULL, GL_TRUE);
+ glXMakeCurrent(dpy, win, ctx);
+ float p = .0f;
+ while (1) {
+ // while (XPending(dpy)) ???
+ XNextEvent(dpy, &xev);
+ if (xev.type == Expose) {
+ XGetWindowAttributes(dpy, win, &gwa);
+ glViewport(0, 0, gwa.width, gwa.height);
+ DrawThing();
+ glXSwapBuffers(dpy, win);
+ } else if (xev.type == KeyPress) {
+ printf("btn:%d\n", xev.xbutton.button);
+ if (xev.xbutton.button==24||xev.xbutton.button==9) {
+ glXMakeCurrent(dpy, None, NULL);
+ glXDestroyContext(dpy, ctx);
+ XDestroyWindow(dpy, win);
+ XCloseDisplay(dpy);
+ exit(0);
+ }
+ }
+ }
+}
diff --git a/main2.c b/main2.c
@@ -0,0 +1,162 @@
+/* tri.c - Minimal X11 + GL/GLU + GLX program drawing one triangle with shaders.
+ Build:
+ gcc -o tri tri.c -lX11 -lGL -lGLU
+ Run:
+ ./tri
+*/
+#define GL_GLEXT_PROTOTYPES 1
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <GL/glx.h>
+
+static const char *vert_src =
+"#version 120\n" /* GLSL 1.10 for wide compatibility */
+"attribute vec3 pos;"
+"void main() { gl_Position = vec4(pos, 1.0); }";
+
+static const char *frag_src =
+"#version 120\n"
+"void main() { gl_FragColor = vec4(0.8, 0.4, 0.2, 1.0); }";
+
+static GLuint compile_shader(GLenum type, const char *src) {
+ GLuint s = glCreateShader(type);
+ glShaderSource(s, 1, &src, NULL);
+ glCompileShader(s);
+ GLint ok = 0;
+ glGetShaderiv(s, GL_COMPILE_STATUS, &ok);
+ if (!ok) {
+ char buf[1024];
+ GLsizei len = 0;
+ glGetShaderInfoLog(s, sizeof(buf)-1, &len, buf);
+ fprintf(stderr, "Shader compile error: %.*s\n", (int)len, buf);
+ exit(1);
+ }
+ return s;
+}
+
+static GLuint link_program(GLuint vs, GLuint fs) {
+ GLuint p = glCreateProgram();
+ glAttachShader(p, vs);
+ glAttachShader(p, fs);
+ glBindAttribLocation(p, 0, "pos"); /* ensure attribute location 0 for simplicity */
+ glLinkProgram(p);
+ GLint ok = 0;
+ glGetProgramiv(p, GL_LINK_STATUS, &ok);
+ if (!ok) {
+ char buf[1024];
+ GLsizei len = 0;
+ glGetProgramInfoLog(p, sizeof(buf)-1, &len, buf);
+ fprintf(stderr, "Program link error: %.*s\n", (int)len, buf);
+ exit(1);
+ }
+ return p;
+}
+
+int main(void) {
+ Display *dpy = XOpenDisplay(NULL);
+ if (!dpy) {
+ fprintf(stderr, "Unable to open X display\n");
+ return 1;
+ }
+
+ /* Choose a visual */
+ static int att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None };
+ XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), att);
+ if (!vi) {
+ fprintf(stderr, "No appropriate visual found\n");
+ return 1;
+ }
+
+ Colormap cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual, AllocNone);
+ XSetWindowAttributes swa;
+ swa.colormap = cmap;
+ swa.event_mask = ExposureMask | KeyPressMask | StructureNotifyMask;
+
+ Window win = XCreateWindow(dpy, RootWindow(dpy, vi->screen),
+ 0, 0, 640, 480, 0, vi->depth, InputOutput,
+ vi->visual, CWColormap | CWEventMask, &swa);
+ XStoreName(dpy, win, "Minimal GL Triangle");
+ XMapWindow(dpy, win);
+
+ /* Create GLX context */
+ GLXContext ctx = glXCreateContext(dpy, vi, NULL, GL_TRUE);
+ if (!ctx) {
+ fprintf(stderr, "Failed to create GLX context\n");
+ return 1;
+ }
+ glXMakeCurrent(dpy, win, ctx);
+
+ /* Compile shaders and link program */
+ GLuint vs = compile_shader(GL_VERTEX_SHADER, vert_src);
+ GLuint fs = compile_shader(GL_FRAGMENT_SHADER, frag_src);
+ GLuint prog = link_program(vs, fs);
+
+ /* Triangle vertices (preset) */
+ const GLfloat verts[] = {
+ 0.0f, 0.6f, 0.0f,
+ -0.6f, -0.4f, 0.0f,
+ 0.6f, -0.4f, 0.0f
+ };
+
+ /* Create simple VBO */
+ GLuint vbo = 0;
+ glGenBuffers(1, &vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glBufferData(GL_ARRAY_BUFFER, sizeof(verts), verts, GL_STATIC_DRAW);
+
+ /* Set up GL state */
+ glViewport(0, 0, 640, 480);
+ glClearColor(0.15f, 0.18f, 0.20f, 1.0f);
+
+ /* Main loop */
+ int running = 1;
+ while (running) {
+ while (XPending(dpy)) {
+ XEvent xe;
+ XNextEvent(dpy, &xe);
+ if (xe.type == Expose) {
+ /* ignore */
+ } else if (xe.type == ConfigureNotify) {
+ XConfigureEvent *ce = (XConfigureEvent*)&xe;
+ glViewport(0, 0, ce->width, ce->height);
+ } else if (xe.type == KeyPress) {
+ running = 0; /* exit on any key */
+ } else if (xe.type == DestroyNotify) {
+ running = 0;
+ }
+ }
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ glUseProgram(prog);
+ glBindBuffer(GL_ARRAY_BUFFER, vbo);
+ glEnableVertexAttribArray(0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);
+
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+
+ glDisableVertexAttribArray(0);
+ glUseProgram(0);
+
+ glXSwapBuffers(dpy, win);
+ /* Simple CPU-side sleep to limit spin (not required) */
+ usleep(1000 * 16);
+ }
+
+ /* Cleanup */
+ glDeleteBuffers(1, &vbo);
+ glDeleteProgram(prog);
+ glDeleteShader(vs);
+ glDeleteShader(fs);
+ glXMakeCurrent(dpy, None, NULL);
+ glXDestroyContext(dpy, ctx);
+ XDestroyWindow(dpy, win);
+ XCloseDisplay(dpy);
+ return 0;
+}