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

一、跨平台环境基本配置

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 pointersreturn 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;// 生成分配VAOglGenVertexArrays(1, &VAO);// 绑定VAO,注意在core模式,没有绑定VAO,opengl拒绝绘制任何东西glBindVertexArray(VAO);GLuint VBO;// 生成一个VBO缓存对象glGenBuffers(1, &VBO);// 绑定VBOglBindBuffer(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)){// inputprocessInput(window);// renderglClearColor(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.hqwc.cn/news/681683.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TensorFlow、pytorch和python对应的版本关系

安装深度学习框架的时候需要考虑版本的关系&#xff0c;不然装了用不了就尴尬了。 深度学习首先得问题就是用CPU跑&#xff0c;还是GPU跑。。当然有英伟达显卡的都想用GPU跑&#xff0c;不然买显卡是做啥、、GPU跑得多块&#xff0c;一下就训练完了。但是有的同学没得gpu&…

操作系统——进程控制

创建进程 fork fork是一个系统调用函数&#xff0c;用来创建子进程&#xff0c;通过多个执行流完成任务。子进程和父进程共用一份代码&#xff0c;子进程数据使用写时拷贝&#xff0c;即子进程数据在创建的时候和父进程相同&#xff0c;但是当要修改数据的时候&#xff0c;子进…

【FreeRTOS 快速入门】-- 1、STM32工程移植FreeRTOS

目录 一、新建STM32工程 为了示范完整的移植过程&#xff0c;我们从0开始&#xff0c;新建一个标准的STM32点灯工程。 &#xff08;本篇以CubeMX作示范&#xff0c;CubeIDE操作近同&#xff0c;可作对比参考&#xff09; 1、新建工程 选择 芯片型号 新建工程 2、搜索芯片型号…

win10 远程桌面无法连接,解决Win10远程桌面无法连接问题的方法

Windows 10操作系统中&#xff0c;远程桌面是一项非常实用的功能&#xff0c;它允许用户从另一台设备远程访问和控制另一台计算机。然而&#xff0c;有时候用户可能会遇到Win10远程桌面无法连接的问题。本文将探讨可能导致这个问题的原因&#xff0c;并提供相应的解决方案。 确…

7-38 数列求和-加强版

题目链接&#xff1a;7-38 数列求和-加强版 一. 题目 1. 题目 2. 输入输出样例 3. 限制 二、代码 1. 代码实现 #include <stdio.h> #include <string.h> #include <malloc.h>void addTerm(char *sum, int A, int N);int main() {int A, N;char *sum;// 读…

C++音视频开发面试题

下面是音视频开发面试题精选&#xff1a; 1、纹理抗锯齿有哪些算法&#xff1f;各有哪些利弊&#xff1f;2、使用 OpenGL PBO 为什么能提高效率&#xff1f;3、iOS 如何使用分段转码&#xff0c;如何设置分片大小&#xff1f;4、VideoToolbox 中是不是不存在平面格式&#xff…

前端css中径向渐变(radial-gradient)的使用

前端css中径向渐变的使用 一、前言二、主要内容说明&#xff08;一&#xff09;、径向渐变的形状1.椭圆形渐变&#xff08;ellipse&#xff09;&#xff0c;源码12.源码1运行效果3.圆形渐变&#xff08;circle&#xff09;&#xff0c;源码24.源码2运行效果 &#xff08;二&…

vue3+ts--实际开发之--table表格打印或者保存

vue3实现指定区域打印&#xff08;导出&#xff09;功能-主要是解决分页内容分割问题 一、 问题页面效果二、 Print.js相关属性 和使用1. 介绍2. 安装引入3. PrintJS参数配置表 三 、解决关于分页文字或者表格被分割问题&#xff0c;解决后如下&#xff1a;1. 设置一个自定义ta…

Linux 第二十四章

&#x1f436;博主主页&#xff1a;ᰔᩚ. 一怀明月ꦿ ❤️‍&#x1f525;专栏系列&#xff1a;线性代数&#xff0c;C初学者入门训练&#xff0c;题解C&#xff0c;C的使用文章&#xff0c;「初学」C&#xff0c;linux &#x1f525;座右铭&#xff1a;“不要等到什么都没有了…

浴室家具360度VR三维沉浸式展示提升品牌价值-深圳华锐视点

随着家居用品市场的持续升温&#xff0c;消费者对家居产品的需求日益旺盛&#xff0c;企业商家也迎来了前所未有的购买热潮。在这个充满机遇与挑战的时代&#xff0c;如何打破传统展示方式的局限&#xff0c;以更直观、更生动的方式呈现家居产品&#xff0c;成为企业提升竞争力…

笑铺日记:一年多赚10W,客户越买越上瘾的新手段

听说过二八原则吗&#xff1f; 一家店80%的利润&#xff0c;是20%的核心客户贡献的。 维护好这20%的客人&#xff0c;更容易换来真金白银噢~ 这20%的客户怎么找&#xff1f; 当然是从你家会员里找&#xff01; 笑铺日记手把手教你&#xff01; 首先&#xff0c;给每个消费…

域名系统(DNS)、DNS 服务器和 IP 地址概念解释

​  域名系统、DNS服务器和IP地址是构成互联网基础设施的重要部分。它们共同协作&#xff0c;使得人们能够方便地使用各种网络服务&#xff0c;而无需去记住复杂的数字地址。那么&#xff0c;域名系统、DNS 服务器和 IP 地址又该如何理解?本文主要讲讲关于这几个名词的概念解…