'OpenGl and GLFW in a docker container

I have a Mac(m1) which only has OpenGL 4.1 which does not support compute shaders, I want to try out raytracing but compute shaders don't work.

If I were to use a docker container to run my OpenGL program, could I use OpenGL 4.3 in the container or is Docker's OpenGL driver dependent on the host machine?

If I could use OpenGL 4.3, how would I be able to run a GLFW window in the container? Would there be a way to see the GLFW window from my Mac?

Here is my Dockerfile and OpenGL code:

#include <glad/glad.h>
#include <glfw/glfw3.h>

#define STB_IMAGE_IMPLEMENTATION
#include <stb/stb_image.h>

#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <sstream>
#include <filesystem>

#define GL_SHADER_FRAG 1
#define GL_SHADER_VERT 2

const char *LoadShader(std::string vertexPath, std::string fragmentPath, int type)
{
std::string vertexCode;
std::string fragmentCode;
std::ifstream vShaderFile;
std::ifstream fShaderFile;

vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);

try
{
    vShaderFile.open(vertexPath);
    fShaderFile.open(fragmentPath);
    std::stringstream vShaderStream;
    std::stringstream fShaderStream;

    vShaderStream << vShaderFile.rdbuf();
    fShaderStream << fShaderFile.rdbuf();

    vShaderFile.close();
    fShaderFile.close();

    vertexCode   = vShaderStream.str();
    fragmentCode = fShaderStream.str();
}
catch(std::ifstream::failure e)
{
    std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ. FILE: " << vertexPath << " " << fragmentPath << std::endl;
}
const char* vShaderCode = vertexCode.c_str();
const char* fShaderCode = fragmentCode.c_str();

if(type == GL_SHADER_VERT).   
    return vShaderCode;
else if(type == GL_SHADER_FRAG)
    return fShaderCode;
}

int main()
{
glfwInit();

glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 2);
glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);

glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);

GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Raytracer", nullptr, nullptr);

if (window == NULL)
{
    std::cout << "Failed to create GLFW window" << std::endl;
    glfwTerminate();
    return -1;
}

glfwMakeContextCurrent(window);

if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
{
    std::cout << "Failed to initialize GLAD" << std::endl;
    return -1;
}

glViewport(0, 0, 800, 600);

std::cout << "OpenGL version: " << glGetString(GL_VERSION) << std::endl;

unsigned int vertexShader = glCreateShader(GL_VERTEX_SHADER);
const char* vertexShaderCode = LoadShader("/Users/nick/Programming/OpenGL-Raytracing/Vertex.glsl", "/Users/nick/Programming/OpenGL-Raytracing/Fragment.glsl", GL_SHADER_VERT);
glShaderSource(vertexShader, 1, &vertexShaderCode, NULL);
glCompileShader(vertexShader);

unsigned int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
const char* fragmentShaderCode = LoadShader("/Users/nick/Programming/OpenGL-Raytracing/Vertex.glsl", "/Users/nick/Programming/OpenGL-Raytracing/Fragment.glsl", GL_SHADER_FRAG);
glShaderSource(fragmentShader, 1, &fragmentShaderCode, NULL);
glCompileShader(fragmentShader);

unsigned int shaderProgram = glCreateProgram();
glAttachShader(shaderProgram, vertexShader);
glAttachShader(shaderProgram, fragmentShader);
glLinkProgram(shaderProgram);

glDeleteShader(fragmentShader);
glDeleteShader(vertexShader);

float vertices[] =
{
    -1.0f,  1.0f, 0.0f,  1.0f, 0.0f, 0.0f,   1.0f, 1.0f,
    -1.0f, -1.0f, 0.0f,  0.0f, 1.0f, 0.0f,   1.0f, 0.0f,
    1.0f, -1.0f, 0.0f,   0.0f, 0.0f, 1.0f,   0.0f, 0.0f,
    1.0f,  1.0f, 0.0f,    1.0f, 1.0f, 0.0f,   0.0f, 1.0f
};
unsigned int indices[] = 
{
    0, 1, 3,
    1, 2, 3
};
float texCoords[] = 
{
    0.0f, 0.0f,
    1.0f, 0.0f,
    0.5f, 1.0f
};

unsigned int VBO, VAO, EBO;
glGenVertexArrays(1, &VAO);
glGenBuffers(1, &VBO);
glGenBuffers(1, &EBO);

glBindVertexArray(VAO);

glBindBuffer(GL_ARRAY_BUFFER, VBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);
    
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
glEnableVertexAttribArray(0);

glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);

glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);

glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);

unsigned int texture;
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

stbi_set_flip_vertically_on_load(true); 

int width, height, nrChannels;
unsigned char *data = stbi_load(std::filesystem::path("/Users/nick/Downloads/rtx1.png").c_str(), &width, &height, &nrChannels, 0);
if (data)
{
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
    glGenerateMipmap(GL_TEXTURE_2D);
}
else
{
    std::cout << "Failed to load texture" << std::endl;
}
stbi_image_free(data);

while(!glfwWindowShouldClose(window))
{
    glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glUseProgram(shaderProgram);

    int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
    glUseProgram(shaderProgram);
    glUniform4f(vertexColorLocation, 1, 0, 0, 0);
    
    glBindTexture(GL_TEXTURE_2D, texture);

    glUseProgram(shaderProgram);
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);

    glfwPollEvents();
    glfwSwapBuffers(window);
}

glfwTerminate();
FROM ubuntu:20.04

COPY ./ /usr/Nick/Maple

RUN apt-get update

RUN apt-get install -y libglfw3-dev
RUN apt-get install -y cmake
RUN apt-get install -y make
RUN apt-get install -y clang
RUN apt-get install -y gobjc++
RUN apt-get install -y build-essential
RUN apt-get install -y mesa-common-dev
RUN apt-get -y install xauth

RUN cd /usr/Nick/Maple && cmake .
RUN cd /usr/Nick/Maple && make

EXPOSE 8887
#RUN cd /usr/Nick/Maple/build/debug && ./OpenGL-Raytracing


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source