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

相关推荐
2401_857026235 分钟前
SpringBoot框架下的服装生产管理自动化
数据库·spring boot·自动化
iQM7512 分钟前
为什么MySQL不建议使用delete删除数据
数据库·mysql
Xerale21 分钟前
Laravel Admin 中的 “Array to String Conversion“ 问题及其解决方法
前端·数据库·笔记·php·laravel
丶21361 小时前
【SQL】深入探索SQL调优:提升数据库性能的全面指南
数据库·sql·性能优化
盒马盒马1 小时前
Redis:分布式 - 哨兵
数据库·redis·分布式
好好学习的人1 小时前
SQL第15课——插入数据
数据库·sql·oracle
技术拾光者1 小时前
Redis 排行榜:实现、操作与性能优化
数据库·redis
傻啦嘿哟1 小时前
SQLAlchemy入门:详细介绍SQLAlchemy的安装、配置及基本使用方法
数据库·oracle
微服务技术分享1 小时前
工程项目管理系统源码与Spring Cloud:实现高效系统管理与二次开发
数据库·spring cloud·工程项目管理系统源码
职场人参2 小时前
视频声音怎么去除?高效的视频声音去除方法
java·服务器·数据库