【小沐学OpenGL】Ubuntu环境下glew的安装和使用

文章目录

  • 1、简介
    • [1.1 OpenGL简介](#1.1 OpenGL简介)
    • [1.2 glew简介](#1.2 glew简介)
  • 2、安装glew
    • [2.1 命令安装glew](#2.1 命令安装glew)
    • [2.2 直接代码安装glew](#2.2 直接代码安装glew)
    • [2.3 cmake代码安装glew](#2.3 cmake代码安装glew)
  • 3、测试glew
    • [3.1 测试glew+freeglut](#3.1 测试glew+freeglut)
    • [3.2 测试glew+glfw](#3.2 测试glew+glfw)
  • 结语

1、简介

1.1 OpenGL简介

Linux 系统中的 OpenGL 是一个跨语言、跨平台的应用程序编程接口(API),用于渲染2D和3D矢量图形。

这里显示 OpenGL 的版本信息:

bash 复制代码
glxinfo| grep version

glxinfo:这是一个用于查询关于 OpenGL 图形系统的信息的命令行工具。它提供了关于图形硬件、驱动程序以及支持的 OpenGL 扩展的详细信息。

grep:这是一个文本搜索工具,用于搜索文本文件或输出中匹配特定模式的行。在这里,它用于搜索包含"version"这个词的行。

glxinfo没有安装,执行如下命令进行安装:

bash 复制代码
sudo apt install mesa-utils

安装成功,继续上面的glxinfo命令如下:

使用 glxgears 命令来测试 OpenGL 的性能,它是一个简单的 OpenGL 程序,显示旋转的齿轮,可以用来测试图形硬件的渲染能力。

bash 复制代码
glxgears 

eglinfo:类似于 glxinfo,但是用于查询有关 EGL (嵌入式系统图形接口) 的信息。

bash 复制代码
eglinfo

1.2 glew简介

GLEW(OpenGL Extension Wrangler Library)是一个跨平台的开源 C/C++ 扩展加载库,用于确定目标平台支持哪些 OpenGL 扩展。它提供了高效的运行时机制,并且已经过多种操作系统的测试,包括 Windows、Linux、Mac OS X、FreeBSD、Irix 和 Solaris。GLEW 使得 OpenGL 核心和扩展功能的声明都包含在单个头文件中,简化了 OpenGL 扩展的使用。

输入glew官方网址:

bash 复制代码
https://glew.sourceforge.net/

2、安装glew

2.1 命令安装glew

bash 复制代码
sudo apt-cache search glew
bash 复制代码
# sudo apt-get install libglew-dbg libglew-dev libglew1.13 libglewmx-dbg libglewmx-dev libglewmx1.13 glew-utils
sudo apt-get -y install glew-utils

在 Linux 系统中安装 GLEW 可以通过包管理器进行。例如,在基于 Debian 的系统(如 Ubuntu)中,可以使用以下命令安装 GLEW:

bash 复制代码
# sudo apt install libglew2.1 libglew-dev
sudo apt-get install libglew-dev
# /usr/lib/x86_64-linux-gnu/libGLEW.so

这将安装 GLEW 的开发文件,包括库文件和头文件。安装后,你可以在项目中包含 GLEW 头文件,并链接到 GLEW 库以使用 OpenGL 扩展。

如果通过cmake编译,在CMakeLists.txt添加如下代码:

bash 复制代码
find_package(GLEW REQUIRED)

target_link_libraries(untitled1 GLEW::GLEW)
  • 完整的CMakeLists.txt:
bash 复制代码
cmake_minimum_required(VERSION 3.16)

project(untitled1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(GLEW REQUIRED)

add_executable(untitled1
  main.cpp
)
target_link_libraries(untitled1 GLEW::GLEW)

include(GNUInstallDirs)
install(TARGETS untitled1
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
  • main.cpp:
cpp 复制代码
#include <GL/glew.h>
#include <iostream>

int main(int argc, char *argv[])
{
    std::cout << "hello yxy" << std::endl;

    // 初始化 GLEW
    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK) {
        std::cout << "glew init failed." << std::endl;
    }
    else {
        std::cout << "glew init ok." << std::endl;
    }

    return 0;
}

编译测试项目代码如下:

再给一个glew测试的例子:

  • main.cpp:
bash 复制代码
#include <GL/glew.h>

#include <stdio.h>
#include <stdlib.h>

#define S(x) SS(x)
#define SS(x) #x

int main(int argc, char* argv[]) {
    printf("GLEW CMake test, %s build\n",
           S(GLEW_CMAKE_TEST_CONFIG));
    printf("-- linked to %s which is %s\n",
           S(GLEW_CMAKE_TEST_TARGET_FILE_NAME),
           S(GLEW_CMAKE_TEST_TARGET_TYPE));
    const GLubyte* v = glewGetString(GLEW_VERSION);
    if(v) {
        printf("-- glewGetString(GLEW_VERSION) returns %s\n-- test passed.\n", v);
        return EXIT_SUCCESS;
    } else {
        printf("-- glewGetString(GLEW_VERSION) returns NULL\n-- test failed.\n");
        return EXIT_FAILURE;
    }
}

卸载libglew-dev库后运行如下:

bash 复制代码
sudo apt autoremove libglew-dev

再编译上面的测试项目代码如下:

2.2 直接代码安装glew

https://glew.sourceforge.net/

如果你需要从源代码编译 GLEW,可以访问 GLEW 的官方网站或其 GitHub 仓库获取源代码。编译 GLEW 通常需要安装一些构建工具,如 make、gcc、git 等。在 Linux 系统上,可以使用以下命令安装这些工具:

bash 复制代码
sudo apt-get install build-essential libxmu-dev libxi-dev libgl-dev

GLEW(OpenGL Extension Wrangler)的官方网站是 http://glew.sourceforge.net/,可以在这个网站上下载GLEW的源代码并进行安装。

wget下载源码如下:

bash 复制代码
wget https://jaist.dl.sourceforge.net/project/glew/glew/2.1.0/glew-2.1.0.tgz

或者使用curl命令下载:

bash 复制代码
curl https://jaist.dl.sourceforge.net/project/glew/glew/2.1.0/glew-2.1.0.tgz -o glew-2.1.0.tgz

执行如下命令进行解压和编译。

bash 复制代码
tar -zxvf glew-2.1.0.tgz
cd glew-2.1.0
#cmake ../cmake -DCMAKE_INSTALL_PREFIX=./install
make
sudo make install

解压glew-2.1.0.tgz如下:

通过make编译源代码如下:

安装编译后文件到系统目录:

bash 复制代码
sudo make install
make clean

查看一下本机上glew被安装的文件夹:

bash 复制代码
find / -name libGLEW.so

使用如下代码,静态链接到特定位置的自定义编译 GLEW 库:

bash 复制代码
#GLEW libraries
add_library(glew_static STATIC IMPORTED)
# add_library(glew_static SHARED IMPORTED)

set_target_properties(glew_static PROPERTIES
    IMPORTED_LOCATION /usr/lib64/libGLEW.a)
    
target_link_libraries(testglew glew_static)

也可以将它与共享库一起使用,只需从 add_library 中删除 STATIC 关键字。

如果通过cmake编译,在CMakeLists.txt添加如下代码:

  • CMakeLists.txt
bash 复制代码
cmake_minimum_required(VERSION 3.16)

project(untitled1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

#####################
# glew
add_library(glew_static STATIC IMPORTED)
set_target_properties(glew_static PROPERTIES
    IMPORTED_LOCATION /usr/lib64/libGLEW.a)

#####################
# opengl
find_package(OpenGL REQUIRED)

add_executable(untitled1
  main.cpp
)
target_link_libraries(untitled1 glew_static OpenGL::GL)

include(GNUInstallDirs)
install(TARGETS untitled1
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
  • main.cpp
bash 复制代码
#include <GL/glew.h>
#include <iostream>

int main(int argc, char *argv[])
{
    std::cout << "hello yxy" << std::endl;

    // 初始化 GLEW
    glewExperimental = GL_TRUE;
    if (glewInit() != GLEW_OK) {
        std::cout << "glew init failed." << std::endl;
    }
    else {
        std::cout << "glew init ok." << std::endl;
    }

    return 0;
}

编译测试项目如下:

2.3 cmake代码安装glew

bash 复制代码
tar -zxvf glew-2.1.0.tgz
cd glew-2.1.0
cd build
mkdir linux
cd linux
cmake ../cmake -DCMAKE_INSTALL_PREFIX=./install
# cmake ../cmake -DCMAKE_INSTALL_PREFIX=/usr/local/thirdparty 
make
make install

执行make install后安装到当前文件夹的install子文件夹里:

3、测试glew

3.1 测试glew+freeglut

  • CMakeLists.txt:
cpp 复制代码
cmake_minimum_required(VERSION 3.16)

project(testglew LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

#####################
# glew
find_package(GLEW REQUIRED)

#####################
# glut
find_package(OpenGL REQUIRED)
find_package(GLUT REQUIRED)
include_directories(${OPENGL_INCLUDE_DIRS})
include_directories(${GLUT_INCLUDE_DIRS})

add_executable(testglew
  main.cpp
)
target_link_libraries(testglew 
    GLEW::GLEW
    ${OPENGL_LIBRARIES} ${GLUT_LIBRARIES}
)

include(GNUInstallDirs)
install(TARGETS testglew
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
  • main.cpp
cpp 复制代码
#include <iostream>
// GLEW
#define GLEW_STATIC
#include <GL/glew.h>
#include <GL/glut.h>

void init(void)
{
    glClearColor(1.0, 1.0, 1.0, 0.0);
    glMatrixMode(GL_PROJECTION);
    gluOrtho2D(0.0, 200.0, 0.0, 160.0);
}

void lineSegment(void)
{
    glClear(GL_COLOR_BUFFER_BIT);
    glColor3f(1.0, 0.0, 0.0);
    glBegin(GL_LINES);
    glVertex2i (180, 15);
    glVertex2i (10, 145);
    glEnd();
    glFlush();
}

int main(int argc, char **argv)
{
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
    glutInitWindowPosition(50, 100);
    glutInitWindowSize(400, 300);
    glutCreateWindow("Example OpenGL Program");

    // Set this to true so GLEW knows to use a modern approach to retrieving function pointers and extensions
    glewExperimental = GL_TRUE;
    // Initialize GLEW to setup the OpenGL Function pointers
    if(glewInit() != GLEW_OK) {
         std::cout << "Failed to initialize GLEW" << std::endl;
         return -1;
    }
    else {
         std::cout << "GLEW is ok!" << std::endl;
    }

    init();
    glutDisplayFunc(lineSegment);
    glutMainLoop();
    return 0;
}

3.2 测试glew+glfw

  • CMakeLists.txt:
bash 复制代码
cmake_minimum_required(VERSION 3.16)

project(untitled1 LANGUAGES CXX)

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

#####################
# glfw
find_package(glfw3 REQUIRED)

#####################
# glew
add_library(glew_static STATIC IMPORTED)
set_target_properties(glew_static PROPERTIES
    IMPORTED_LOCATION /usr/lib64/libGLEW.a)

#####################
# opengl
find_package(OpenGL REQUIRED)

add_executable(untitled1
  main.cpp
)
target_link_libraries(untitled1 glew_static OpenGL::GL glfw)

include(GNUInstallDirs)
install(TARGETS untitled1
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
  • main.cpp
cpp 复制代码
#include <GL/glew.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 = 300;

// 顶点着色器,GLSL语言
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(0.0f, 1.0f, 0.0f, 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, "Ubuntu Opengl, yxy", 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;
    // }
    if(glewInit() != GLEW_OK) {
        std::cout << "Failed to initialize GLEW" << 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(); // shaderProgram 是多个着色器合并之后并最终链接完成的版本
    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;
    //创建VAO对象
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);
    //创建VBO对象,把顶点数组复制到一个顶点缓冲中,供OpenGL使用
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO); // 缓冲绑定到GL_ARRAY_BUFFER
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); // 顶点数据复制到缓冲的内存中

    //解释顶点数据方式
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0); // 顶点数据的解释
    glEnableVertexAttribArray(0);

    // 解绑VAO
    glBindVertexArray(0);
    // 解绑VBO
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    // render loop
    while (!glfwWindowShouldClose(window))
    {
        // input
        processInput(window);

        // render
        glClearColor(1.0f, 0.7f, 0.7f, 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);
}

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

相关推荐
蜀黍@猿40 分钟前
【C++ 基础】从C到C++有哪些变化
c++
Am心若依旧40941 分钟前
[c++11(二)]Lambda表达式和Function包装器及bind函数
开发语言·c++
真真-真真43 分钟前
WebXR
linux·运维·服务器
zh路西法1 小时前
【C++决策和状态管理】从状态模式,有限状态机,行为树到决策树(一):从电梯出发的状态模式State Pattern
c++·决策树·状态模式
轩辰~1 小时前
网络协议入门
linux·服务器·开发语言·网络·arm开发·c++·网络协议
lxyzcm1 小时前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
蜀黍@猿2 小时前
C/C++基础错题归纳
c++
雨中rain2 小时前
Linux -- 从抢票逻辑理解线程互斥
linux·运维·c++
Bessssss2 小时前
centos日志管理,xiao整理
linux·运维·centos
s_yellowfish2 小时前
Linux服务器pm2 运行chatgpt-on-wechat,搭建微信群ai机器人
linux·服务器·chatgpt