CMake创建跨平台OPenGL工程(学习笔记)

news2024/11/29 2:30:14

一、跨平台环境基本配置

1、环境搭建

1)linux OpenGL环境搭建参考:ubuntu18.04 OpenGL开发(显示YUV)_ubuntu opengl-CSDN博客

https://blog.51cto.com/cerana/6433535

2)windows下环境搭建

OpenGL+Visual Studio2022+GLFW+glad详细配置教程_给vs配置glfw和glad-CSDN博客

2、创建cmake

    这里测试使用的图形界面使用QT。其中路径后面讲解

    主要有几个注意事项:

1)linux下需要添加

 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-error=register")

2)windows下需要设置vitual studio

set(LIBRARY_GLFW_PATH "${PROJECT_SOURCE_DIR}/lib-vc2022")

cmake_minimum_required(VERSION 3.5)

SET(TARGET "QTGL")

project(${TARGET} VERSION 0.1 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

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

if(WIN32)
else()
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-error=register")
endif()

set(QTGL_GLAPI_PATH "${PROJECT_SOURCE_DIR}/GLAPI")
set(GLAD_FOLDER_INCLUDE_PATH "${PROJECT_SOURCE_DIR}/glad/include")
set(GLAD_FOLDER_SOURCE_PATH  "${PROJECT_SOURCE_DIR}/glad/src")
set(GLM_FOLDER_INCLUDE_PATH  "${PROJECT_SOURCE_DIR}/glm")
set(GLFW_FOLDER_INCLUDE_PATH  "${QTGL_GLAPI_PATH}/glfw")

if(WIN32)
    set(LIBRARY_GLFW_PATH "${PROJECT_SOURCE_DIR}/lib-vc2022")
    LINK_DIRECTORIES("${LIBRARY_GLFW_PATH}")
endif()

include_directories(${QTGL_GLAPI_PATH})
include_directories(${GLAD_FOLDER_INCLUDE_PATH})
include_directories(${GLM_FOLDER_INCLUDE_PATH})
include_directories(${GLFW_FOLDER_INCLUDE_PATH})

file(GLOB GLAPI_HEADERS "${QTGL_GLAPI_PATH}/*.h")
source_group("GLAPI/include" FILES ${GLAPI_HEADERS})

file(GLOB GLAPI_SOURCES "${QTGL_GLAPI_PATH}/*.cpp")
source_group("GLAPI/source" FILES ${GLAPI_SOURCES})

file(GLOB_RECURSE GLAD_INCLUDE "${GLAD_FOLDER_INCLUDE_PATH}/*.*")
source_group("glad/include" FILES ${GLAD_INCLUDE})

file(GLOB GLAD_SOURCE "${GLAD_FOLDER_SOURCE_PATH}/*.*")
source_group("glad/src" FILES ${GLAD_SOURCE})

SET(QTUI_PATH "${PROJECT_SOURCE_DIR}/QTUI")

file(GLOB_RECURSE QTUI_FILES "${QTUI_PATH}/*.*")
source_group("QTUI" FILES ${QTUI_FILES})


set(ALL_SOURCES
        ${GLAPI_HEADERS}
        ${GLAPI_SOURCES}
        ${GLAD_INCLUDE}
        ${GLAD_SOURCE}
        ${QTUI_FILES}
)

ADD_EXECUTABLE(${TARGET} WIN32 ${ALL_SOURCES})

find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Widgets)
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets)


target_link_libraries(${TARGET} PRIVATE Qt${QT_VERSION_MAJOR}::Widgets)

if(WIN32)
    target_link_libraries(${TARGET} PRIVATE debug "${LIBRARY_GLFW_PATH}/glfw3.lib" optimized "${LIBRARY_GLFW_PATH}/glfw3.lib")
    target_link_libraries(${TARGET} PRIVATE debug "${LIBRARY_GLFW_PATH}/glfw3_mt.lib" optimized "${LIBRARY_GLFW_PATH}/glfw3_mt.lib")
    target_link_libraries(${TARGET} PRIVATE debug "${LIBRARY_GLFW_PATH}/glfw3dll.lib" optimized "${LIBRARY_GLFW_PATH}/glfw3dll.lib")
else()
    target_link_libraries(${TARGET} PRIVATE glfw3)
    target_link_libraries(${TARGET} PRIVATE GL)
    target_link_libraries(${TARGET} PRIVATE X11)
    target_link_libraries(${TARGET} PRIVATE m)
    target_link_libraries(${TARGET} PRIVATE pthread)
    target_link_libraries(${TARGET} PRIVATE dl)
endif()

3、第三方库文件

1)glad和glm

glad下载:https://glad.dav1d.de/,下载后得到glad.zip

把glad整个文件夹放置到工程目录下,然后,把src下的glad.c改为glad.cpp。

把glm整个文件夹放置到工程目录下,不需要额外的修改。

2)glfw

glfw下载,Download | GLFW

windows下,需要将编译好的glfw库放置到工程下。如图:

 3)整体工程结构如图:

4、QT界面文件QTUI

创建一个QDialog或者QMainWindow,带有.ui文件,可以使用uic指令将其转换为.h文件。

二、OPENGL 简单示例

1、初始化工程

1)初始化glfw,具体解释看:OpenGL学习(一) 绘制一个三角形 - 简书

int DrawApi::initialGlfw()
{
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    // glad: load all OpenGL function pointers
    
    return 0;
}

2)创建窗口:

int DrawApi::createWindow(string windowName, OUT GLFWwindow*& window)
{
    // glfw window creation
    // --------------------
    window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, windowName.c_str(), NULL, NULL);
    if (window == NULL)
    {
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        cout << "Failed to initialize GLAD" << endl;
        return -1;
    }

    glViewport(0, 0, 800, 800);

    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);  // 窗体能够根据拉动变化

    return 0;
}

3)顶点着色器

int DrawApi::createVertexShader(OUT GLuint& vertexShader, const char* vertexShaderSource)
{
    //1.初始化着色器
    //创建一个着色器类型
    vertexShader = glCreateShader(GL_VERTEX_SHADER);
    //把代码复制进着色器中
    glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
    //编译顶点着色器
    glCompileShader(vertexShader);

    int success;
    char infoLog[512];
    glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &success);

    //判断是否编译成功
    if (!success) {
        glGetShaderInfoLog(vertexShader, 512, NULL, infoLog);
        cout << "error when vertex compile:" << infoLog << endl;
        return -1;
    }
    return 0;
}

4)片元着色器

int DrawApi::createFragmentShader(OUT GLuint& fragmentShader, const char* fragmentShaderSource)
{
    fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);

    glCompileShader(fragmentShader);

    int success;
    char infoLog[512];
    glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &success);

    //判断是否编译成功
    if (!success) {
        glGetShaderInfoLog(fragmentShader, 512, NULL, infoLog);
        cout << "error when fragment compile:" << infoLog << endl;
        return -1;
    }
    return 0;
}

5)编译程序

int DrawApi::createProgram(GLuint& vertexShader, GLuint& fragmentShader, OUT GLuint& shaderProgram)
{
    //链接,创建一个程序
    shaderProgram = glCreateProgram();

    //链接上共享库
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    //链接
    glLinkProgram(shaderProgram);

    int success;
    char infoLog[512];
    glGetProgramiv(shaderProgram, GL_LINK_STATUS, &success);
    if (!success) {
        glGetProgramInfoLog(shaderProgram, 512, NULL, infoLog);
        cout << "error when link compile:" << infoLog << endl;
        return -1;
    }

    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    return 0;
}

6)绘制三角形

int DrawApi::drawTriangles(const vector<vector<float>>& triangelValues)
{
    //1.会先绑定顶点
    //2.绑定缓冲区
    //3.接着把顶点输入到顶点缓冲去中
    //4.把缓冲区的数据传送到着色器中
    //5.输出到屏幕。

    if (initialGlfw() < 0)
        return -1;

    GLFWwindow* window = nullptr;
    if (createWindow("learnOpenGL", window) < 0)
        return -2;

    GLuint vertexShader;
    if (createVertexShader(vertexShader, VERTEX_SHADER) < 0)
        return -3;

    GLuint fragmentShader;
    if (createFragmentShader(fragmentShader, FRAGMENT_SHADER) < 0)
        return -4;

    GLuint shaderProgram;
    if (createProgram(vertexShader, fragmentShader, shaderProgram) < 0)
        return -5;

    if (triangelValues.size() == 0)
        return -6;

    if (triangelValues.size() > 1256)
        return -7;

    float vertices[4096] = {0};

    for (int i = 0; i < triangelValues.size(); i++)
    {
        for (int j = 0; j < 3; j++)
        {
             vertices[3 * i + j] = triangelValues[i][j];
        }
    }

    GLuint VAO;
    // 生成分配VAO
    glGenVertexArrays(1, &VAO);
    // 绑定VAO,注意在core模式,没有绑定VAO,opengl拒绝绘制任何东西
    glBindVertexArray(VAO);

    GLuint VBO;
    // 生成一个VBO缓存对象
    glGenBuffers(1, &VBO);
    // 绑定VBO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);
    // 类型为GL_ARRAY_BUFFER 第二第三参数说明要放入缓存的多少,GL_STATIC_DRAW当画面不动的时候推荐使用
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);

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

        // render
        glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT);


        glUseProgram(shaderProgram);
        //绑定数据
        glBindVertexArray(VAO);
        //绘制一个三角形
        //从0开始,3个
        glDrawArrays(GL_TRIANGLES, 0, triangelValues.size() * 3);

        glBindVertexArray(0);

        // glfw: swap buffers and poll IO events (keys pressed/released, mouse moved etc.)
        // -------------------------------------------------------------------------------
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);

    // glfw: terminate, clearing all previously allocated GLFW resources.
    // ------------------------------------------------------------------
    glfwTerminate();
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1659028.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

前端css中线性渐变(linear-gradient)的使用

前端css中线性渐变 一、前言二、关键词句三、主要内容说明&#xff08;一&#xff09;、线性渐变方向1.角度调整方向2.负值角度&#xff0c;源码13.源码1运行效果4.关键字调整方向5.to right向右线性渐变&#xff0c;源码26.源码2运行效果 &#xff08;二&#xff09;、线性渐变…

hyper-v启动centos7虚拟机不能联网

虚拟网卡要和之前虚拟机里面设置的GATEWAY一致。 安装CentOS遇到Error setting up base repository换url 或者换镜像包iso(这个有用&#xff09; 没掌握摸Yu的精髓 好累啊

Linux 中 POSIX 互斥信号量(互斥锁)的使用

目录 一、互斥锁的介绍二、使用方法三、测试代码 一、互斥锁的介绍 在Linux系统中&#xff0c;特别是在ARM架构的嵌入式系统中&#xff0c;互斥量&#xff08;Mutex&#xff09;用于保护共享资源不被多个线程或任务同时访问&#xff0c;从而防止数据竞争和不一致性。 POSIX 互斥…

Springboot集成Mybatispuls操作mysql数据库-04

MyBatis-Plus&#xff08;简称MP&#xff09;是一个MyBatis的增强工具&#xff0c;在MyBatis的基础上只做增强而不做改变。它支持所有MyBatis原生的特性&#xff0c;因此引入MyBatis-Plus不会对现有的MyBatis构架产生任何影响。MyBatis-Plus旨在简化开发、提高效率&#xff0c;…

JavaEE企业级开发中常用的Stream流

介绍 在Java编程中&#xff0c;Stream流是Java 8引入的一个重要概念&#xff0c;它提供了一种新的处理集合的方式&#xff0c;可以更加简洁、高效地进行数据操作。Stream流支持各种常见的操作&#xff0c;比如过滤、映射、排序、聚合等&#xff0c;同时也支持并行处理&#xf…

Go的安装与配置

安装 https://go.dev/dl/ 以Windows上安装为例&#xff1a; 下一步下一步&#xff0c;记住安装位置 安装完成后 win rcmd 键入go version检查是否安装成功 配置 Go 工作区 Go 在组织项目文件方面与其他编程语言不同。 Go 是在工作区的概念下工作的。但是从版本 1.11 开始&…

Dreamweaver 2021 for Mac 激活版:网页设计工具

在追求卓越的网页设计道路上&#xff0c;Dreamweaver 2021 for Mac无疑是您的梦幻之选。这款专为Mac用户打造的网页设计工具&#xff0c;集强大的功能与出色的用户体验于一身。 Dreamweaver 2021支持多种网页标准和技术&#xff0c;让您能够轻松创建符合现代网页设计的作品。其…

RespeakPro对口型数字人使用教程

RespeakPro可以将您的视频与音频生成100%精准对口型的视频。与Respeak差别是效率高效果更好。是自媒体制作数字人视频必备黑科技AI. 支持多国语言音频和唱歌音频对口型! 1&#xff1a;系统要求 软件运行支持32/64位window 10/11系统, 无硬件要求,不用显卡也能快速运行。 2&a…

vue+springboot实现excel批量数据的导入导出

①后端配置端口&#xff1a;修改UserController UserController&#xff1a; package com.example.springboot.controller;import cn.hutool.core.util.StrUtil; import cn.hutool.poi.excel.ExcelReader; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.…

教大家一键下载1688图片信息

电商图片是商品的视觉身份证&#xff0c;对销量有着决定性影响。它们不仅是展示产品&#xff0c;更是讲述品牌故事&#xff0c;激发情感共鸣的工具。高质量的图片能瞬间吸引顾客目光&#xff0c;准确传达产品细节&#xff0c;建立起顾客的信任与购买意愿。在无法亲身体验商品的…

全自动减压器法二氧化碳气容量测试仪:饮料行业的革新与未来

全自动减压器法二氧化碳气容量测试仪&#xff1a;饮料行业的革新与未来 一、引言 在追求品质与效率的现代饮料生产领域&#xff0c;全自动减压器法二氧化碳气容量测试仪凭借其高精度、高效率及无人工干预的显著优势&#xff0c;正逐渐成为行业的标杆。特别是在碳酸饮料的生产中…

【考古篇】Attension is all you need

Transformer 文章目录 Transformer1. What2. Why3. How3.1 Encoder3.2 Decoder3.3 Attention3.4 Application3.5 Position-wise Feed-Forward Networks(The second sublayer)3.6 Embeddings and Softmax3.7 Positional Encoding3.8 Why Self-Attention 1. What A new simple n…

labview技术交流-字符串数组连接成字符串

应用场景 我们可能需要将一维的字符串数组转换成一整条字符串&#xff0c;然后方便记录在数据库或表格中的一个单元格中。 代码展示 方案一 我们使用for循环完成这样的功能需求&#xff0c;见下图&#xff1a; 这种方案可能相对基础和普通&#xff0c;但是它更方便和易于扩展…

JavaSwing技术实现一个电子表程序

使用JavaSwing技术实现一个简单的电子表盘&#xff0c;如下所示。 下载链接 有兴趣的读者可以点击链接下载&#xff0c;博主承诺绝对真实有效。

PyQt5中的事件与信号处理

文章目录 1. 简介1.1事件(Event)1.2 信号(Signal)与槽(Slot)1.3 自定义信号 2. 一个信号与槽的简单示例13. 一个信号与槽的简单示例24. 事件发送者5. 创建自定义信号6. 一个简单计算器 1. 简介 在PyQt5中&#xff0c;事件和信号处理是GUI编程的核心概念。事件是指用户操作或系…

2024年数维杯数维杯数学建模A题思路+论文+代码+结果

A 题 多源机会信号建模与导航分析 尽管全球卫星定位系统下的定位导航技术已成熟&#xff0c;但考虑到室内、 隧道、建筑密集区等复杂环境或全球卫星定位系统被毁失灵等突发场 景&#xff0c;会发生全球卫星定位系统拒止情况&#xff0c;无法有效定位导航。因此&#xff0c; 需要…

Coze扣子开发指南:用免费API自己创建插件

虽然Coze扣子现在插件商店已经有几百个插件了&#xff0c;但相对于海量人群的众多差异化需求&#xff0c;还是远远不够的。如果插件商店没有合适的插件&#xff0c;其实完成可以自己创建&#xff0c;过程也很简单&#xff0c;不需要编写任何代码。 首先打开个人空间&#xff0…

JavaSwing课程设计-实现一个计算器程序

通过JavaSwing技术来实现计算器小程序&#xff0c;效果如下。 源码下载链接 源码下载 博主承诺真实有效&#xff0c;私信可提供支持

Linux系统搭建Gitlab开源仓库管理系统并实现公网环境访问本地私有库

文章目录 前言1. 下载Gitlab2. 安装Gitlab3. 启动Gitlab4. 安装cpolar5. 创建隧道配置访问地址6. 固定GitLab访问地址6.1 保留二级子域名6.2 配置二级子域名 7. 测试访问二级子域名 前言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xf…

内网渗透windows命令绕过

①选项字符替换 有一些命令是unix移植来的,可以使用-&#xff08;横短线&#xff09;&#xff0c;Windows原生选项连接符为/&#xff08;正斜杠&#xff09; 例&#xff1a; ping -h ping /h 像 find之类的命令无法兼容- windows中打开文件,支持直接打开和\.(反斜杠)点的形…