Last active
January 24, 2024 11:09
-
-
Save japajoe/62670f36b36c68f98eec599586606791 to your computer and use it in GitHub Desktop.
OpenGL context with X11 and Glad
This file contains hidden or 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
| //Compiling: | |
| //g++ main.cpp -o app -lX11 -lGL -ldl | |
| //Don't forget to add glad to your sources | |
| #include <X11/Xlib.h> | |
| #include "glad/glad.h" | |
| #include <GL/glx.h> | |
| #include <iostream> | |
| static int CreateTriangle(); | |
| static void DestroyTriangle(); | |
| static void RenderTriangle(); | |
| GLuint vertexShader = 0; | |
| GLuint fragmentShader = 0; | |
| GLuint shaderProgram = 0; | |
| GLuint VAO = 0; | |
| GLuint VBO = 0; | |
| float vertices[] = { | |
| -0.5f, -0.5f, 0.0f, | |
| 0.5f, -0.5f, 0.0f, | |
| 0.0f, 0.5f, 0.0f | |
| }; | |
| const char *vertexShaderSource = R"( | |
| #version 330 core | |
| layout (location = 0) in vec3 aPos; | |
| void main() { | |
| gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); | |
| } | |
| )"; | |
| const char *fragmentShaderSource = R"( | |
| #version 330 core | |
| out vec4 FragColor; | |
| void main() { | |
| FragColor = vec4(1.0, 0.5, 0.2, 1.0); | |
| } | |
| )"; | |
| int main() | |
| { | |
| Display *display; | |
| Window window; | |
| XEvent event; | |
| GLXContext glContext; | |
| // Open a connection to the X server | |
| display = XOpenDisplay(NULL); | |
| if (display == NULL) { | |
| fprintf(stderr, "Unable to open display\n"); | |
| return 1; | |
| } | |
| // Create a window | |
| window = XCreateSimpleWindow(display, DefaultRootWindow(display), 0, 0, 400, 300, 0, 0, None); | |
| XSelectInput(display, window, ExposureMask | KeyPressMask | StructureNotifyMask); | |
| XMapWindow(display, window); | |
| // Set up GLX | |
| int glxAttribs[] = {GLX_RGBA, GLX_DOUBLEBUFFER, None}; | |
| XVisualInfo *visualInfo = glXChooseVisual(display, DefaultScreen(display), glxAttribs); | |
| glContext = glXCreateContext(display, visualInfo, NULL, GL_TRUE); | |
| glXMakeCurrent(display, window, glContext); | |
| if(!gladLoadGLLoader((GLADloadproc)glXGetProcAddress)) | |
| { | |
| return -1; | |
| } | |
| CreateTriangle(); | |
| // Event loop | |
| while (1) { | |
| XNextEvent(display, &event); | |
| switch(event.type) | |
| { | |
| case Expose: | |
| { | |
| glClearColor(0, 0, 0, 1); | |
| glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); | |
| RenderTriangle(); | |
| glXSwapBuffers(display, window); | |
| break; | |
| } | |
| case ConfigureNotify: | |
| { | |
| int width = event.xconfigure.width; | |
| int height = event.xconfigure.height; | |
| glViewport(0, 0, width, height); | |
| break; | |
| } | |
| case KeyPress: | |
| { | |
| break; | |
| } | |
| } | |
| } | |
| DestroyTriangle(); | |
| // Close the connection to the X server | |
| glXMakeCurrent(display, None, NULL); | |
| glXDestroyContext(display, glContext); | |
| XCloseDisplay(display); | |
| return 0; | |
| } | |
| int CreateTriangle() | |
| { | |
| // Create and compile the vertex shader | |
| vertexShader = glCreateShader(GL_VERTEX_SHADER); | |
| glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); | |
| glCompileShader(vertexShader); | |
| // Check for shader compilation errors | |
| GLint success; | |
| glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success); | |
| if (!success) { | |
| char infoLog[512]; | |
| glGetShaderInfoLog(vertexShader, sizeof(infoLog), NULL, infoLog); | |
| fprintf(stderr, "Vertex shader compilation failed:\n%s\n", infoLog); | |
| return -1; | |
| } | |
| // Create and compile the fragment shader | |
| fragmentShader = glCreateShader(GL_FRAGMENT_SHADER); | |
| glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL); | |
| glCompileShader(fragmentShader); | |
| // Check for shader compilation errors | |
| glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success); | |
| if (!success) { | |
| char infoLog[512]; | |
| glGetShaderInfoLog(fragmentShader, sizeof(infoLog), NULL, infoLog); | |
| fprintf(stderr, "Fragment shader compilation failed:\n%s\n", infoLog); | |
| return -1; | |
| } | |
| // Create a shader program and link the shaders | |
| shaderProgram = glCreateProgram(); | |
| glAttachShader(shaderProgram, vertexShader); | |
| glAttachShader(shaderProgram, fragmentShader); | |
| glLinkProgram(shaderProgram); | |
| // Check for shader program linking errors | |
| glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success); | |
| if (!success) { | |
| char infoLog[512]; | |
| glGetProgramInfoLog(shaderProgram, sizeof(infoLog), NULL, infoLog); | |
| fprintf(stderr, "Shader program linking failed:\n%s\n", infoLog); | |
| return -1; | |
| } | |
| glGenVertexArrays(1, &VAO); | |
| glGenBuffers(1, &VBO); | |
| glBindVertexArray(VAO); | |
| glBindBuffer(GL_ARRAY_BUFFER, VBO); | |
| glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); | |
| glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); | |
| glEnableVertexAttribArray(0); | |
| return 0; | |
| } | |
| void DestroyTriangle() | |
| { | |
| glDeleteVertexArrays(1, &VAO); | |
| glDeleteBuffers(1, &VBO); | |
| glDeleteProgram(shaderProgram); | |
| glDeleteShader(vertexShader); | |
| glDeleteShader(fragmentShader); | |
| } | |
| void RenderTriangle() | |
| { | |
| glUseProgram(shaderProgram); | |
| glBindVertexArray(VAO); | |
| glDrawArrays(GL_TRIANGLES, 0, 3); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment