OpenGL-ES 学习(6)---- Ubuntu OES 环境搭建

OpenGL-ES Ubuntu 环境搭建

此的方法在 ubuntu 和 deepin 上验证都可以成功搭建

目录

    • OpenGL-ES Ubuntu 环境搭建
      • 软件包安装
      • 第一个三角形
        • 基于 glfw 实现
        • 基于 X11 实现

软件包安装

sudo apt install libx11-dev
sudo apt install libglfw3 libglfw3-dev
sudo apt-get install libgles2-mesa
sudo apt-get install libgles2-mesa-dev

检查环境是否安装成功:
/usr/include 下是否有 EGL GL GLES2 GLES3 的目录

Note: 上面的环境中同时安装了 x11 和 glfw,实际上只需要安装一个自己需要的即可, x11 和 glfw 都是为 OES 环境对接到窗口系统中,
个人觉得 x11 的API 对 egl 的封装比较标准话一些,可以用于学习 egl 的api

第一个三角形

基于 glfw 实现
#include <stdio.h>
#include <time.h>
#include <GLES2/gl2.h>
#include <GLFW/glfw3.h>// Vertex Shader source code
// Vertex Shader source code
const GLchar* vertexSource ="#version 300 es\n""layout(location = 0) in vec4 position;\n""void main() {\n""    gl_Position = position;\n""}\n";// Fragment Shader source code
const GLchar* fragmentSource ="#version 300 es\n""precision mediump float;\n""out vec4 fragColor;\n""void main() {\n""    fragColor = vec4(1.0, 0.0, 0.0, 1.0);\n""}\n";int main() {printf("main testsuites enter n");// Initialize GLFWif (!glfwInit()) {fprintf(stderr, "Failed to initialize GLFW\n");return -1;}// Create a windowed mode window and its OpenGL contextGLFWwindow* window = glfwCreateWindow(640, 480, "opengles-glfw", NULL, NULL);if (!window) {fprintf(stderr, "Failed to create GLFW window\n");glfwTerminate();return -1;}// Make the window's context currentglfwMakeContextCurrent(window);// Load the OpenGL ES functionsglClearColor(0.0f, 0.0f, 0.0f, 1.0f);// Create and compile the vertex shaderGLint status;GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);glShaderSource(vertexShader, 1, &vertexSource, NULL);glCompileShader(vertexShader);// Check for compilation errorsif (status != GL_TRUE) {char buffer[512];glGetShaderInfoLog(vertexShader, 512, NULL, buffer);fprintf(stderr, "Vertex Shader Compile Error: %s\n", buffer);}// Create and compile the fragment shaderGLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);glShaderSource(fragmentShader, 1, &fragmentSource, NULL);glCompileShader(fragmentShader);glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &status);if (status != GL_TRUE) {char buffer[512];glGetShaderInfoLog(fragmentShader, 512, NULL, buffer);fprintf(stderr, "Fragment Shader Compile Error: %s\n", buffer);}// Link the vertex and fragment shader into a shader programGLuint shaderProgram = glCreateProgram();glAttachShader(shaderProgram, vertexShader);glAttachShader(shaderProgram, fragmentShader);glLinkProgram(shaderProgram);// Specify the layout of the vertex dataGLfloat vertices[] = {0.0f,  0.5f, 0.0f,0.5f, -0.5f, 0.0f,-0.5f, -0.5f, 0.0f,};GLuint vbo;glGenBuffers(1, &vbo);glBindBuffer(GL_ARRAY_BUFFER, vbo);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// Specify the layout of the vertex dataglUseProgram(shaderProgram);glBindBuffer(GL_ARRAY_BUFFER, vbo);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), 0);glEnableVertexAttribArray(0);// Main loopwhile (!glfwWindowShouldClose(window)) {// calculate for extecute time,about 16.6ms every period{struct timespec currentts;static uint64_t timeInMiliSeconds = 0;clock_gettime(CLOCK_REALTIME, &currentts);uint64_t currentMilliseconds = currentts.tv_sec * 1000LL + currentts.tv_nsec / 1000000;int periodInMs = currentMilliseconds - timeInMiliSeconds;timeInMiliSeconds = currentMilliseconds;printf("current time in milliseconds %lld period:%d\n", currentMilliseconds,(periodInMs > 0 ? periodInMs : -1));}// Clear the screenglClear(GL_COLOR_BUFFER_BIT);// Draw the triangleglUseProgram(shaderProgram);glBindBuffer(GL_ARRAY_BUFFER, vbo);glEnableVertexAttribArray(0);glDrawArrays(GL_TRIANGLES, 0, 3);// Swap front and back buffersglfwSwapBuffers(window);// Poll for and process eventsglfwPollEvents();}// Clean upglDeleteBuffers(1, &vbo);glDeleteProgram(shaderProgram);glDeleteShader(vertexShader);glDeleteShader(fragmentShader);glfwDestroyWindow(window);glfwTerminate();return 0;
}

基本步骤如下:

  1. GLFW初始化和窗口创建
    初始化GLFW并设置OpenGL ES上下文版本
    创建窗口并设置上下文,将创建的窗口用于opengl-es上下文,此时opengl-es和系统的窗口系统相关联 , 创建着色器,编译着色器,最近将其链接到一个程序对象

  2. 编译顶点着色器和片段着色器,并将它们链接到一个程序中

  3. 定义一个简单的三角形顶点数据,并绘制三角形

  4. 设置视口,清除颜色缓冲区,加载顶点数据,并调用绘制命令

  5. 主循环中不断交换缓冲区并处理事件,以保持窗口响应。

  6. 删除程序和着色器,销毁窗口,并终止GLFW

对应的 CMakeLists.txt 实现

cmake_minimum_required(VERSION 3.27)
project(opengles_glfw C)set(CMAKE_C_STANDARD 11)find_package(PkgConfig REQUIRED)
pkg_search_module(GLFW REQUIRED glfw3)include_directories(${GLFW_INCLUDE_DIRS})add_executable(opengles_glfw main.c)
target_link_libraries(opengles_glfw ${GLFW_LIBRARIES} GLESv2)

在程序主循环中,还添加了计时相关的代码逻辑,在glfw 的模式下,主循环也是跟屏幕刷新率相同也是60Hz, 可以看到每次循环体的执行间隔都是 16.6ms

current time in milliseconds 1717986851291 period:14
current time in milliseconds 1717986851308 period:17
current time in milliseconds 1717986851324 period:16
基于 X11 实现

基于 X11 实现的 opengl-es 环境如下:

#include <malloc.h>
#include "glesbasicTriangle.h"typedef struct {GLuint programObject;
} UserData;static int initInternal(ESContext* esContext) {UserData *userData = esContext->userData;// Vertex Shader source codeconst char* vertexShaderSource ="#version 300 es                            \n""layout(location = 0) in vec4 a_position;   \n""void main() {\n""   gl_Position = a_position;\n""}\n";// Fragment Shader source codeconst char* fragmentShaderSource ="#version 300 es                            \n""precision mediump float;\n""layout(location = 0) out vec4 outColor;             \n""void main() {\n""   outColor = vec4(1.0, 0.0, 0.0, 1.0);\n""}\n";// 这里封装了 createshader-compilershader-createprogramobject-link programoobject 的操作GLuint programObject = esLoadProgram(vertexShaderSource, fragmentShaderSource);if (programObject == 0) {return GL_FALSE;}// Store the program objectuserData->programObject = programObject;return GL_TRUE;
}static int drawLoopInternal(ESContext* esContext) {// Vertex dataGLfloat vertices[] = {0.0f,  0.5f, 0.0f,-0.5f, -0.5f, 0.0f,0.5f, -0.5f, 0.0f};// Set the viewportglViewport(0, 0, 640, 480);UserData *userData = esContext->userData;glUseProgram(userData->programObject);// Clear the color bufferglClearColor(0.0, 0.0, 0.0, 1.0);glClear(GL_COLOR_BUFFER_BIT);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vertices);glEnableVertexAttribArray(0);// Draw the triangleglDrawArrays(GL_TRIANGLES, 0, 3);// Swap bufferseglSwapBuffers(esContext->eglDisplay, esContext->eglSurface);
}static int cleanupInternal(ESContext* esContext) {printf("%s enter!.\n",__FUNCTION__);UserData *userData = esContext->userData;glDeleteProgram(userData->programObject);eglDestroySurface(esContext->eglDisplay, esContext->eglSurface);eglDestroyContext(esContext->eglDisplay, esContext->eglContext);eglTerminate(esContext->eglDisplay);XDestroyWindow(esContext->x_display, esContext->win);XCloseDisplay(esContext->x_display);return GL_TRUE;
}int testbasicDrawTriangle(ESContext* esContext) {printf("%s enter!.\n", __FUNCTION__);esContext->userData = (UserData*)malloc(sizeof(UserData));initInternal(esContext);while (1) {XEvent xev;while (XPending(esContext->x_display)) {XNextEvent(esContext->x_display, &xev);if (xev.type == KeyPress) {cleanupInternal(esContext);}}drawLoopInternal(esContext);}}

其中在调用 testbasicDrawTriangle 之前, 还有窗口系统的准备工作需要完成,实现就是下面的函数:esCreateWindow 其他文件中实现, main 函数在调用 testbasicDrawTriangle 之前,就已经调用了 esCreateWindow 函数

GLboolean esCreateWindow ( ESContext *esContext, const char *title, GLint width, GLint height, GLuint flags )
{
// Open X11 displayEGLint majorVersion;EGLint minorVersion;Display* x_display = XOpenDisplay(NULL);if (x_display == NULL) {printf("Failed to open X display\n");return GL_FALSE;}esContext->x_display = x_display;esContext->width = width;esContext->height = height;// Create X11 windowWindow root = DefaultRootWindow(esContext->x_display);XSetWindowAttributes swa;swa.event_mask = ExposureMask | PointerMotionMask | KeyPressMask;Window win = XCreateWindow(esContext->x_display, root,0, 0, width, height, 0,CopyFromParent, InputOutput,CopyFromParent, CWEventMask,&swa);XMapWindow(esContext->x_display, win);XStoreName(esContext->x_display, win, title);esContext->win = win;// Initialize EGLEGLDisplay egl_display = eglGetDisplay((EGLNativeDisplayType)esContext->x_display);if (egl_display == EGL_NO_DISPLAY) {printf("Failed to get EGL display\n");return GL_FALSE;}esContext->eglDisplay = egl_display;if (!eglInitialize(esContext->eglDisplay, &majorVersion, &minorVersion)) {printf("Failed to initialize EGL\n");return GL_FALSE;}printf("%s majorVersion:%d minorVersion:%d \n", __FUNCTION__, majorVersion, minorVersion);// Choose an EGL configEGLint configAttribs[] = {EGL_SURFACE_TYPE, EGL_WINDOW_BIT,EGL_BLUE_SIZE, 8,EGL_GREEN_SIZE, 8,EGL_RED_SIZE, 8,EGL_DEPTH_SIZE, 8,EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,EGL_NONE};EGLint attribList[] ={EGL_RED_SIZE,       5,EGL_GREEN_SIZE,     6,EGL_BLUE_SIZE,      5,EGL_ALPHA_SIZE,     ( flags & ES_WINDOW_ALPHA ) ? 8 : EGL_DONT_CARE,EGL_DEPTH_SIZE,     ( flags & ES_WINDOW_DEPTH ) ? 8 : EGL_DONT_CARE,EGL_STENCIL_SIZE,   ( flags & ES_WINDOW_STENCIL ) ? 8 : EGL_DONT_CARE,EGL_SAMPLE_BUFFERS, ( flags & ES_WINDOW_MULTISAMPLE ) ? 1 : 0,// if EGL_KHR_create_context extension is supported, then we will use// EGL_OPENGL_ES3_BIT_KHR instead of EGL_OPENGL_ES2_BIT in the attribute listEGL_RENDERABLE_TYPE, GetContextRenderableType ( esContext->eglDisplay ),EGL_NONE};EGLConfig egl_config;EGLint numConfigs;eglChooseConfig(esContext->eglDisplay, attribList, &egl_config, 1, &numConfigs);if (numConfigs != 1) {printf("Failed to choose EGL config\n");return GL_FALSE;}// Create an EGL window surfaceEGLSurface egl_surface = eglCreateWindowSurface(esContext->eglDisplay, egl_config, (EGLNativeWindowType)esContext->win, NULL);if (egl_surface == EGL_NO_SURFACE) {printf("Failed to create EGL surface\n");return GL_FALSE;}esContext->eglSurface = egl_surface;// Create an EGL contextEGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };EGLContext egl_context = eglCreateContext(esContext->eglDisplay, egl_config, EGL_NO_CONTEXT, contextAttribs);if (egl_context == EGL_NO_CONTEXT) {printf("Failed to create EGL context\n");return GL_FALSE;}esContext->eglContext = egl_context;// Make the context currentif (!eglMakeCurrent(esContext->eglDisplay, esContext->eglSurface , esContext->eglSurface , esContext->eglContext)) {printf("Failed to make EGL context current\n");return GL_FALSE;}return GL_TRUE;
}

esCreateWindow 的代码中,使用 x_display 关联到了 egl 的display 对象中,同时,使用在 eglCreateWindowSurface 中 使用了 x11 创建的 win handle 创建 EGLSurface

其余绘制三角形的步骤和 glfw 的基本一致
实现效果如下:
basic_triangles

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

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

相关文章

新旧torch中傅里叶变换实现(fft)

由泰勒级数我们知道&#xff0c;一个函数可以被分解成无穷个幂函数叠加的形式&#xff0c;于是同样地&#xff0c;一个周期函数也可以被分解成多个周期函数叠加&#xff0c;于是自然而然地&#xff0c;三角函数符合这个需求&#xff0c;由傅里叶级数我们可以将周期函数分解成无…

unity 简易异步socket

1.unity 同步socket 改异步 using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Net.Sockets; using UnityEngine.UI; using System.Threading; using System;public class Echo : MonoBehaviour {//定义套接字Socket socket;//UG…

ubuntu的home内存不足的解决办法(win和ubuntu双系统)

这种解决办法前提是windows和ubuntu双系统 首先在windows系统上创建一个空的硬盘分区 然后在ubuntu系统上把这个空的硬盘放在主目录里 然后可以把东西存在这个文件夹中 如下图&#xff0c;但实际主目录的内存没有变&#xff0c;以后存东西就在这个文件夹里面就好了 具体操作…

在typora中利用正则表达式,批量处理图片

一&#xff0c;png格式 在 Typora 中批量将 HTML 图片标签转换为简化的 Markdown 图片链接&#xff0c;且忽略 alt 和 style 属性&#xff0c;可以按照以下步骤操作&#xff1a; 打开 Typora 并加载你的文档。按下 Ctrl H&#xff08;在 Windows/Linux 上&#xff09;或 Cmd…

大数据与人工智能在保险行业数字化转型中的应用

随着科技的快速发展&#xff0c;大数据和人工智能&#xff08;AI&#xff09;技术在保险行业中扮演着越来越重要的角色&#xff0c;推动了保险行业的数字化转型。通过收集和分析海量的用户数据&#xff0c;利用先进的人工智能算法&#xff0c;保险公司能够更准确地评估风险&…

JavaScript算法实现dfs查找省市区路径

需求 存在如下数组&#xff0c;实现一个算法通过输入区名&#xff0c;返回省->市->区格式的路径&#xff0c;例如输入西湖区&#xff0c;返回浙江省->杭州市->西湖区。 // 定义省市区的嵌套数组 const data [{name: "浙江省",children: [{name: "…

华为云下Ubuntu20.04中Docker的部署

我想用Docker拉取splash&#xff0c;Docker目前已经无法使用&#xff08;镜像都在国外&#xff09;。这导致了 docker pull 命令的失败&#xff0c;原因是timeout。所以我们有必要将docker的源设置在国内&#xff0c;直接用国内的镜像。 1.在华为云下的Ubuntu20.04因为源的原因…

element 树组件 tree 横向纵向滚动条

Html <el-cardshadow"hover"class"solo flex-2"style"height: calc(100vh - 1.6rem); border: 1px solid #ebeef5"><div slot"header" class"clearfix"><span>问题分类</span></div><div …

TCPListen客户端和TCPListen服务器

创建项目 TCPListen服务器 public Form1() {InitializeComponent();//TcpListener 搭建tcp服务器的类&#xff0c;基于socket套接字通信的//1创建服务器对象TcpListener server new TcpListener(IPAddress.Parse("192.168.107.83"), 3000);//2 开启服务器 设置最大…

【three.js】设置three.js全屏展示,并解决大小动态变化

目录 一、设置全屏 二、canvas画布宽高度动态变化 一、设置全屏 这个很简单,直接用代码读取当前全屏需要的长宽即可。 const width = window.innerWidth; //窗口文档显示区的宽度作为画布宽度 const height = window.innerHeight; //窗口文档显示区的高度作为画布高度 二、…

快手爬票概述

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 无论是出差还是旅行&#xff0c;都无法离开交通工具的支持。现如今随着科技水平的提高&#xff0c;高铁与动车成为人们喜爱的交通工具。如果想要知道…

GenICam标准(一)

系列文章目录 GenICam标准&#xff08;一&#xff09; GenICam标准&#xff08;二&#xff09; GenICam标准&#xff08;三&#xff09; GenICam标准&#xff08;四&#xff09; GenICam标准&#xff08;五&#xff09; GenICam标准&#xff08;六&#xff09; 文章目录 系列文…

Nature|高性能柔性纤维电池 (柔性智能织物/可穿戴电子/界面调控/柔性电池/柔性电子)

2024年4月24日,复旦大学彭慧胜(Huisheng Peng)院士团队,在《Nature》上发布了一篇题为“High-performance fibre battery with polymer gel electrolyte”的论文,陆晨昊(Chenhao Lu)、Haibo Jiang和Xiangran Cheng为论文共同第一作者。论文内容如下: 一、 摘要 用聚合物凝…

人工智能模型组合学习的理论和实验实践

组合学习&#xff0c;即掌握将基本概念结合起来构建更复杂概念的能力&#xff0c;对人类认知至关重要&#xff0c;特别是在人类语言理解和视觉感知方面。这一概念与在未观察到的情况下推广的能力紧密相关。尽管它在智能中扮演着核心角色&#xff0c;但缺乏系统化的理论及实验研…

边缘计算采集网关解决方案:为企业提供高效、灵活的数据处理方案-天拓四方

一、企业背景 某大型制造企业&#xff0c;位于国内某经济发达的工业园区内&#xff0c;拥有多个生产线和智能化设备&#xff0c;致力于提高生产效率、降低运营成本。随着企业规模的扩大和生产自动化的推进&#xff0c;该企业面临着海量数据处理、实时响应和网络安全等多重挑战…

基于Spring Boot的智能分析平台

项目介绍&#xff1a; 智能分析平台实现了用户导入需要分析的原始数据集后&#xff0c;利用AI自动生成可视化图表和分析结论&#xff0c;改善了传统BI系统需要用户具备相关数据分析技能的问题。该项目使用到的技术是SSMSpring Boot、redis、rabbitMq、mysql等。在项目中&#…

中职C语言程序设计课程教学解决方案

前言 在当今信息时代&#xff0c;计算思维被视为核心素养和关键能力&#xff0c;而程序设计课程作为其培养的载体显得尤为重要。然而&#xff0c;中职教育中的C语言程序设计课程仍然面临传统教学模式的局限&#xff0c;缺乏对学生计算思维的引导&#xff0c;这不仅影响了学生的…

vue3+electron搭建桌面软件

vue3electron开发桌面软件 最近有个小项目, 客户希望像打开 网易云音乐 那么简单的运行起来系统. 前端用 Vue 会比较快一些, 因此决定使用 electron 结合 Vue3 的方式来完成该项目. 然而, 在实施过程中发现没有完整的博客能够记录从创建到打包的流程, 摸索一番之后, 随即梳理…

Content type ‘application/x-www-form-urlencoded;charset=UTF-8‘ not supported

Content type application/x-www-form-urlencoded;charsetUTF-8 not supported 问题背景新增页面代码改造 问题背景 这里有一个需求&#xff0c;前端页面需要往后端传参&#xff0c;参数包括主表数据字段以及子表数据字段&#xff0c;由于主表与子表为一对多关系&#xff0c;在…

DenseNet完成Cifer10任务的效果验证

本文章是针对论文《2017-CVPR-DenseNet-Densely-Connected Convolutional Networks》中实验的复现&#xff0c;使用了几乎相同的超参数 目录 一、论文中的实验 1.准确率 2.参数效率 3.不同网络结构之间的比较 二、超参数: 三、复现的实验结果&#xff1a; 1.DenseNet20…