2

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
genpfault
  • 51,148
  • 11
  • 85
  • 139
  • 1
    Possibly a duplicate: https://stackoverflow.com/questions/65802625/develop-using-opengl-4-x-on-osx-big-sur In short: No, there is currently no way to get OpenGL >4.1 on MacOS. In fact, OpenGL has been deprecated by Apple and will be removed entirely in the future. Apple forces developers to use their own Metal API. – Jonathan S. May 16 '22 at 15:15
  • 1
    @JonathanS. If there's no way to run OpenGl 4.1+ on Mac, are there any tools/libraries that can transpile OpenGL to metal. I know MoltenVK does something like that for Vulkan, so would there be some thing like that to run OpenGL on metal – Nick Developer May 16 '22 at 16:32
  • 1
    Such a library currently does not exist. There really is no way to get GL >4.1 on a Mac at the moment. The Mesa project is developing its own graphics driver for the Apple M1 right now; however, that driver is still far from complete and will only be usable if you install Linux on your M1 Macbook (once it's gotten to a usable state). You may have better luck using Vulkan via MoltenVK (or just use Apple's Metal API directly). In theory, running Mesa's Zink on MoltenVK on Metal might work, but I wouldn't bet on it as Zink is also still in early development. – Jonathan S. May 16 '22 at 17:08
  • So what you're saying is that is no way to run OpenGL 4.6+ on mac. One more question, is docker capabile of running OpenGL 4.3+, is Docker dependant on the drivers of the mac, or does it have some way to use it's own drivers. – Nick Developer May 16 '22 at 20:36
  • Docker is dependent on the operating system you're running it on. It does not provide its own drivers. – Jonathan S. May 16 '22 at 21:14
  • What about a VM? – Nick Developer May 16 '22 at 21:16
  • If you run a VM on your M1 Macbook, it does not have a graphics card and therefore no working OpenGL. Your Macbook simply doesn't have a graphics card in it that is (currently) compatible with GL 4.6, so there is no way to get GL 4.6 on this hardware. (Or anything above 4.1 for that matter.) – Jonathan S. May 16 '22 at 21:18
  • Alright thanks for the help, I was considering learning vulkan a while back, I think I'll try compute shaders/raytracing with that. Thanks for the help. – Nick Developer May 16 '22 at 21:20

0 Answers0