c++ Docker容器中的OpenGl和GLFW

nbnkbykc  于 4个月前  发布在  Docker
关注(0)|答案(1)|浏览(80)

我有一台Mac(m1),它只有OpenGL 4.1,不支持计算着色器,我想尝试光线跟踪,但计算着色器不工作。
如果我使用Docker容器来运行我的OpenGL程序,我可以在容器中使用OpenGL 4.3吗?Docker的OpenGL驱动程序是否依赖于主机?
如果我可以使用OpenGL 4.3,我将如何能够在容器中运行GLFW窗口?是否有办法从我的Mac看到GLFW窗口?
下面是我的Dockerfile和OpenGL代码:

#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();

个字符

yeotifhr

yeotifhr1#

你可能不能,因为OpenGL不是一个可以从一个地方转移到另一个地方的库,它集成在图形处理器中,所以你有点坚持那个版本,据我所知,像GLFW这样的库只是帮助通过API访问函数。

相关问题