1. 只创建了一个子线程,专门用于渲染
  2. 子线程中打开了另一个 Display, 并在此Display下创建了 opengl context 和 多个Window
  3. 子线程有自己的消息循环,因为Window产生的消息貌似只能由创建Window的Display来XNextEvent,主线程中的Display抓不到这些事件
  4. 主线程中也open了一个Display,并创建了一个gl context,当做资源shared的context,同时也用于初始化 glew
  5. 尝试过两个线程共享一个Display,并使用了XInitThreads,和 Lock等方法,但最终失败,子线程中调用 glXMakeCurrent时被阻塞了,原因不明
  6. 这个demo的将render放到了单独的线程,但并不是每个Window一个线程,而是所有的RenderWindow在同一个线程中渲染
  7. 另外发现,虽然子线程的 glcontext 创建时,引用了主线程的 glcontext,但资源无法在其间共享,只能应用于与同一个glcontext的不同窗口,猜想是因为,两个线程用了不同的Display导致

#include <cassert>
#include <string>// opengl
#include <GL/glew.h>
// x
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
#include <GL/glx.h>const auto EVENT_MASK = ExposureMask | KeyPressMask | StructureNotifyMask;
GLXContext  g_mainGLContext;
bool g_exitFlag = false;struct Device {Display *display;Window windowRoot;int defaultScreen;GLXFBConfig *fbConfig;XVisualInfo *visualInfo;Colormap colormap;
};struct MakeCurrent{const Device & m_device;GLXDrawable m_oldWindow;GLXContext m_oldContext;MakeCurrent(const Device & device, GLXDrawable win, GLXContext context): m_device(device){m_oldContext = glXGetCurrentContext();m_oldWindow = glXGetCurrentDrawable();glXMakeCurrent(device.display, win, context);}~MakeCurrent() {glXMakeCurrent(m_device.display, m_oldWindow, m_oldContext);}
};void openDevice(Device & device){auto displayName = getenv("DISPLAY"); assert(displayName);device.display = XOpenDisplay(displayName); assert(device.display);device.defaultScreen = DefaultScreen(device.display);int nelements, att[] = {GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DOUBLEBUFFER, True, GLX_DEPTH_SIZE, 16, None};device.fbConfig = glXChooseFBConfig(device.display, device.defaultScreen, att, &nelements); assert(device.fbConfig);device.visualInfo = glXGetVisualFromFBConfig(device.display, *device.fbConfig); assert(device.visualInfo);device.windowRoot = RootWindow(device.display, device.defaultScreen);device.colormap = XCreateColormap(device.display, device.windowRoot, device.visualInfo->visual, AllocNone);
}GLXContext createGLContext(const Device & device, GLXContext sharedContext){auto context = glXCreateContext(device.display, device.visualInfo, sharedContext, GL_TRUE); assert(context);return context;
}void initGLEW(const Device & device, GLXContext context){MakeCurrent mc(device, device.windowRoot, context);auto err = glewInit(); assert(GLEW_OK == err);
}Window createWindow(const Device & device){XSetWindowAttributes swa;swa.colormap = device.colormap;swa.event_mask = EVENT_MASK;unsigned long valueMask = CWColormap | CWEventMask;auto window = XCreateWindow(device.display, device.windowRoot, 100, 100, 320, 240, 0,device.visualInfo->depth, InputOutput, device.visualInfo->visual,valueMask, &swa);XMapWindow(device.display, window);XFlush(device.display);return window;
}void destroyWindow(const Device & device, Window window){auto iResult = XUnmapWindow(device.display, window); assert(iResult);iResult = XDestroyWindow(device.display, window); assert(iResult);
}void destroyGLContext(const Device & device, GLXContext context){if (glXGetCurrentContext() == context) {auto bResult = glXMakeCurrent(device.display, None, nullptr); assert(bResult);}glXDestroyContext(device.display, context);
}void closeDevice(const Device & device){XFreeColormap(device.display, device.colormap);XFree(device.fbConfig);XFree(device.visualInfo);XCloseDisplay(device.display);
}// ===========================================================================================// ===========================================================================================
GLuint buffer;
void initResource(const Device & device, Window window, GLXContext context){MakeCurrent mc(device, window, context);float data[] = {0.5f, 0.5f,-0.5f, 0.5f,-0.5f, -0.5f,0.5f, -0.5f,};glGenBuffers(1, &buffer);glBindBuffer(GL_ARRAY_BUFFER, buffer);glBufferData(GL_ARRAY_BUFFER, sizeof(data), data, GL_STATIC_DRAW);
}void destroyResource(const Device & device, Window window, GLXContext context){MakeCurrent mc(device, window, context);glDeleteBuffers(1, &buffer);
}void render(){glClearColor(1.0f, 0.5f, 0.5f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glBindBuffer(GL_ARRAY_BUFFER, buffer);glEnableClientState(GL_VERTEX_ARRAY);glVertexPointer(2, GL_FLOAT, sizeof(float)<<1, 0);glDrawArrays(GL_QUADS, 0, 4);glEnableClientState(GL_VERTEX_ARRAY);glBindBuffer(GL_ARRAY_BUFFER, 0);
}void eventLoopWithRender(const Device & device, GLXContext context){XEvent event;for (;;){XNextEvent(device.display, &event);switch (event.type){case Expose:{MakeCurrent mc(device, event.xexpose.window, context);render();glXSwapBuffers(device.display, event.xexpose.window);} break;case ConfigureNotify: break;case KeyPress: {auto keySys = XkbKeycodeToKeysym(device.display, event.xkey.keycode, 0,(event.xkey.state & ShiftMask) ? 1 : 0);if (keySys == XK_Escape) return;}break;}}
}void *threadRender(void *) {Device device; openDevice(device);Window window1 = createWindow(device);Window window2 = createWindow(device);Window window3 = createWindow(device);Window window4 = createWindow(device);auto context = createGLContext(device, g_mainGLContext);initResource(device, window1, context);eventLoopWithRender(device, context);destroyResource(device, window1, context);destroyWindow(device, window1);destroyWindow(device, window2);destroyWindow(device, window3);destroyWindow(device, window4);destroyGLContext(device, context);closeDevice(device);g_exitFlag = true;
}int main(){Device device; openDevice(device);g_mainGLContext = createGLContext(device, nullptr);initGLEW(device, g_mainGLContext);// initResource(device, device.windowRoot, g_mainGLContext);pthread_t thread;auto iResult = pthread_create(&thread, nullptr, threadRender, nullptr); assert(iResult == 0);for (;!g_exitFlag;){pthread_yield();}// destroyResource(device, device.windowRoot, g_mainGLContext);destroyGLContext(device, g_mainGLContext);closeDevice(device);return 0;
}

demo code - Multi-thread render in GLX相关推荐

  1. penpyxl basic function demo code

    Openpyxl basic function demo code demo code: #!/usr/bin/env python # -*- coding: utf-8 -*- "&qu ...

  2. 从Demo到Engine(二) -- Render Queue Sort

    从Demo到Engine(二) -- Render Queue Sort 仅供个人学习使用,请勿转载,勿用于任何商业用途. 渲染队列排序是引擎渲染步骤中一个非常重要的部分,稍微有经验的图形程序员都知道 ...

  3. 【红宝书】OpenGL Demo code编译与运行

    本人就职于国际知名终端厂商,负责modem芯片研发. 在5G早期负责终端数据业务层.核心网相关的开发工作,目前牵头6G算力网络技术标准研究. [红宝书]OpenGL Demo code编译与运行 文章 ...

  4. Windows API GetProcAddress 及demo code

    GetProcAddress函数检索指定的动态链接库(DLL)中的输出库函数地址. 函数原型: FARPROC GetProcAddress( HMODULE hModule, // DLL模块句柄 ...

  5. Multi thread: std::promise

    2019独角兽企业重金招聘Python工程师标准>>> 前面我们了解到可以使用std::shared_future/std::shared_future在多个其他线程中处理另外一个线 ...

  6. QT打开文件选择框(demo code)

    QString filepath = QFileDialog::getOpenFileName(NULL, "请选择数据文件", "", "CSV(* ...

  7. PIC16F1829 单片机配置和DEMO CODE

  8. Fatal signal 11 (SIGSEGV) at 0x00000000 (code=1), thread 16169 (Thread-1035)

    线程异常终止,找不到原因,最后发现这个错误是因为线程里面的一个方法调用了jni的方法,程序在jni里面出错异常终止,我的错误是传递的参数错误,jni那边空指针,这个错误的纠结的地方就是不会报什么错误和 ...

  9. centos下打包electron_从零搭建Electron应用 的一系列简单的 Demo

    Electron 是一个优秀的跨平台桌面应用程序开源库,目前接触 Electron 的开发者也越来越多.但是笔者发现,目前社区里缺少对初学者足够友好的入门教程来帮助初学者用 Electron 搭建一个 ...

最新文章

  1. AI一分钟|美团确认收购摩拜;特斯拉今年第一季度产量创历史新高
  2. ROS安装:Ubuntu18.04安装配置ROS-melodic
  3. Css的filter常用濾波器屬性及語句大全
  4. JMX和Spring –第3部分
  5. 产品经理需要懂技术吗?懂到什么程度?
  6. 调用图片文件夹中的任意图片随机显示_【分享】文字、表格、公式图片识别神器V0.8...
  7. Excel 关于新建xls文件 新建sheet 合并sheet的VBA操作代码
  8. Unit5 Survival Shooter笔记3
  9. Maven学习五之Nexus中各repository介绍
  10. cpu压测 windows_小白求问怎么用AIDA64进行CPU压力测试
  11. 接口测试系列之——接口安全测试
  12. 2021-2027全球及中国油田钻机行业研究及十四五规划分析报告
  13. 2022暑期学校——简单实现2021年电子设计竞赛国赛题目
  14. 东营网站服务器部署,联通东营服务器dns地址
  15. 物体成瘾性_如何克服数字成瘾和更多的意志力
  16. 【JS】H5打开支付宝
  17. linux环境下如何重装系统,linux 怎么重装系统?
  18. Sublime Emmet 插件安装教程 Tab 快捷键无法使用问题解决
  19. 《第六周RFID作业》物联112118 林家辉
  20. 计算机网络:网络层——网际协议IP

热门文章

  1. app稳定测试- AppetizerIO
  2. 如何通过网页查看真机或者虚拟机的数据库
  3. 组件式GIS开发总结(一)
  4. 响应式表格(table-responsive)表头与表数据位置偏移
  5. 2018 与 我的技术之路
  6. 涉密信息搜索工具_干货amp;鸡汤 | 能在网上搜到的,就不要求人了(如何搜到看起来不好搜的信息)...
  7. 北京推进政务服务“区块链+电子证照”应用
  8. 乐学堂掌财社天风:股票价值理论是什么意思
  9. 平均无故障时间100万小时_平均无故障时间100万小时
  10. 智慧公路精华主题汇总(更新至20220828)