//Compiling: //g++ main.cpp -o app -lX11 -lGL -ldl //Don't forget to add glad to your sources #include #include "glad/glad.h" #include #include 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); }