Ubuntu20.04搭建OpenGL环境(glfw+glad)

Ubuntu20.04搭建OpenGL环境(glfw+glad)

Linux环境搭建

本文在VMware安装Ubuntu20.04桌面版的环境下搭建OpenGL,按照本文搭建完成后可以执行LearnOpenGL网站上的demo

关于VMware可自行到VMware Workstation Pro | CN下载

关于Ubuntu20.04桌面版可自行到官网或Index of /ubuntu-releases/20.04.6/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror下载

这里窗口系统是X11,如果最新版Ubuntu窗口系统应该是Wayland那配置方法可能有所差异,没有实测过。

啰嗦几句基操~

关于虚拟机和物理机的通信:

可以采用scp命令或建立共享文件夹的方式。

关于建立共享文件夹的几个步骤:

  • 在编辑虚拟机设置里选择一个共享文件夹
  • 在开启虚拟机的瞬间,不断点击选项栏的虚拟机,直到刷出安装VMware Tools是可以点击的状态,然后点击安装。
  • 进入虚拟机后/mnt/hgfs在这个目录下会发现和物理机的共享文件夹

正文开始

安装g++

sudo apt install g++

安装mesa工具

sudo apt install mesa-utils

查看opengl的版本

glxinfo -B | grep 'OpenGL version string'

得到  `OpenGL version string: 4.1 (Compatibility Profile) Mesa 21.2.6`  字样,我们记住自己的版本号,我的是4.1

安装xorg依赖(GLFW的依赖)

sudo apt install xorg-dev

下载glfw源码进行编译

bash 复制代码
git clone https://github.com/glfw/glfw
cd glfw
cmake -S . -B build
cd build
make
sudo make install

安装GLAD

登录到GLAD官网,点这里。只需要把API中gl的版本设置成我们刚才查看的版本即可(作者是4.1)。最后点击GENERATE

这时浏览器会跳至文件页,我们把glad.zip文件保存到本地并解压。

解压之后得到一个include目录,和一个src目录

我们首先把include这个目录里的内容移动到标准头目录下,sudo mv include/* /usr/local/include

src目录下有个glad.c文件我们需要把他放到项目文件中,一会再弄!

创建项目

bash 复制代码
mkdir opengl_code
cd opengl_code
  • glad.c文件copy过来

  • 创建一个build目录 mkdir build

  • 创建CMakeLists.txt文件,并添加以下内容

    cmake_minimum_required(VERSION 2.8)
    set(CMAKE_C_STANDARD 11)
    set(CMAKE_CXX_STANDARD 14)

    project(test)

    find_package(glfw3 REQUIRED)
    find_package( OpenGL REQUIRED )
    include_directories( {OPENGL_INCLUDE_DIRS} ) file(GLOB project_file glad.c main.cpp) add_executable({PROJECT_NAME} ${project_file})

    target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES} glfw)

  • 创建main.cpp文件,并添加以下内容

cpp 复制代码
#include <glad/glad.h>
#include <GLFW/glfw3.h>
 
#include <iostream>
 
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow *window);
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;
 
const char *vertexShaderSource = "#version 330 core\n" 
    "layout (location = 0) in vec3 aPos;\n"
    "void main()\n"
    "{\n"
    "   gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" 
    "}\0";
const char *fragmentShaderSource = "#version 330 core\n"
    "out vec4 FragColor;\n"
    "void main()\n"
    "{\n"
    "   FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);\n"
    "}\n\0";
 
int main()
{
    // glfw: initialize and configure
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif
 
    // glfw window creation
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LearnOpenGL", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);
 
    // glad: load all OpenGL function pointers
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }
 
 
    // build and compile our shader program
    // ------------------------------------
    // vertex shader
    int vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL); 
    glCompileShader(vertexShader);
    // check for shader compile errors
    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // fragment shader
    int fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
    glCompileShader(fragmentShader);
    // check for shader compile errors
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);
    if (!success)
    {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::FRAGMENT::COMPILATION_FAILED\n" << infoLog << std::endl;
    }
    // link shaders
    int shaderProgram = glCreateProgram(); 
    glAttachShader(shaderProgram, vertexShader); 
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);
    // check for linking errors
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
    }
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
 
 
    float vertices[] = {
        -0.5f, -0.5f, 0.0f, // left  
         0.5f, -0.5f, 0.0f, // right 
         0.0f,  0.5f, 0.0f  // top   
    }; 
 
    unsigned int VBO, VAO;
    glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);
    glGenBuffers(1, &VBO);
    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);
 
	glBindVertexArray(0); 
    glBindBuffer(GL_ARRAY_BUFFER, 0); 
 
    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))
    {
        // input
        // -----
        processInput(window);
 
        // render
        // ------
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);
 
        // draw our first triangle
        glUseProgram(shaderProgram); 
        glBindVertexArray(VAO); 
        glDrawArrays(GL_TRIANGLES, 0, 3); 
 
        glfwSwapBuffers(window);
        glfwPollEvents();
    }
 
    // optional: de-allocate all resources
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);
    glfwTerminate();
    
    return 0;
}
 
void processInput(GLFWwindow *window)
{
    if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
        glfwSetWindowShouldClose(window, true);
}
 
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
    glViewport(0, 0, width, height);
}
  • 创建run.sh文件,并添加以下内容

    cd build
    cmake ..
    make
    ./test
    cd ..

完成

现在运行bash run.sh 即可执行OpneGL程序,效果如下:

PS

如果想通过gdb调试的话,那需要手动进行编译。

  • sudo apt-get install libglfw3-dev libgl1-mesa-dev

  • g++ -O0 -g glad.c main.cpp -lglfw3 -ldl -lGL -lpthread

这样就可以gdb a.out

相关推荐
夜泉_ly19 分钟前
MySQL -安装与初识
数据库·mysql
qq_529835351 小时前
对计算机中缓存的理解和使用Redis作为缓存
数据库·redis·缓存
月光水岸New4 小时前
Ubuntu 中建的mysql数据库使用Navicat for MySQL连接不上
数据库·mysql·ubuntu
狄加山6754 小时前
数据库基础1
数据库
我爱松子鱼4 小时前
mysql之规则优化器RBO
数据库·mysql
chengooooooo4 小时前
苍穹外卖day8 地址上传 用户下单 订单支付
java·服务器·数据库
Rverdoser5 小时前
【SQL】多表查询案例
数据库·sql
Galeoto5 小时前
how to export a table in sqlite, and import into another
数据库·sqlite
人间打气筒(Ada)6 小时前
MySQL主从架构
服务器·数据库·mysql
leegong231116 小时前
学习PostgreSQL专家认证
数据库·学习·postgresql