随着Vulkan的引入,我们的图形技术的发展到达了一个新的顶点,但是呢,我们的老干爹OpenGL作为落日余晖,他在一些Vulkan才有的新功能上,也提供了一些支持,现在我们来讨论一下OpenGL之多线程渲染。

这里要补一补课:

windows上调用openGL最原始的原始方式

大概流程是这样的详情请见:https://gitee.com/GProReat/codes/bjptwd3hglozmi25esn4v31

1.获取句柄, 在win32或者MFC里面可以直接获取HWND,但是在glut,glfw,sdl等可以通过GetActiveWindow来获取HWND。

2.GetDC,这个是获取窗口的DC,  HDC ( Handle To Device Context)是图像的设备描述表,窗口显示上下文句柄,其中可以进行图形显示。

3.PixelFormat的支持,这里可以看刚才代码段里面PixelFormat的设置

4.创建OpenGL的上下文wglCreateContext, 以及切换到当前的上下文,wglMakeCurrent,传入HGLRC类型的object。

5.初始化操作  各种开关比如: depthTest,AlphaTest,DepthFunc,Texture2等操作。

6.在窗口的绘制的时候,也就是WM_PAINT相应的时候处理绘制。

  这里关键一点是,调用OpenGL绘制之后使用SwapBuffers,还有glFlush。

7.资源释放。

note:windows上使用openGL来渲染,大家可以找MFC或者win32上的OpenGL绘制。

接下来开始我们的主题:openGL多线程渲染

根据我的测试,HGLRC 的创建与线程无关,也就是说目前HGLRC可以在另外一个线程创建(需要在当前线程wglShareLists),也可以在当前线程创建,

下面为核心代码:

this->hGLRC2 = wglCreateContext(hDC);
wglShareLists(hGLRC2, hGLRC);
std::thread th([this]() {
wglMakeCurrent(hDC, hGLRC2);
texAnotherThread.LoadFromFile1("1.jpg");
});
th.join();

当然我们根据测试,也能发现,HGLRC在shared之前或者之后加载资源,都能做到共享

    hGLRC = wglGetCurrentContext();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
std::thread th([this]() {
hGLRC2 = wglCreateContext(hDC);
wglMakeCurrent(hDC, hGLRC2);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
texAnotherThread.LoadFromFile1("1.jpg");
}
th.join();
wglShareLists(hGLRC, hGLRC2);

还有根据我的测试wglShareLists(hGLRC, hGLRC2); 他实际上这两个参数顺序是有讲究的,如果在创建完上下文之后,直接共享,那么这俩参数顺序没有影响,如果在hGLRC2里加载完tetxure,那么只能wglShareLists(hGLRC2,hGLRC)

代码如下:(顺序无关的)

void MultiThreadTexture_App::Init()
{
hWnd = GetActiveWindow();
hDC = GetDC(hWnd);
hGLRC = wglGetCurrentContext();
hGLRC2 = wglCreateContext(hDC);
wglShareLists(hGLRC, hGLRC2); //顺序无关
isRunning = true;
std::thread th([this]() {
wglMakeCurrent(hDC, hGLRC2);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
texAnotherThread.LoadFromFile1("1.jpg");
});
th.join();
}
void MultiThreadTexture_App::Init()
{
hWnd = GetActiveWindow();
hDC = GetDC(hWnd);
hGLRC = wglGetCurrentContext();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
hGLRC2 = wglCreateContext(hDC); isRunning = true;
std::thread th([this]() {
wglMakeCurrent(hDC, hGLRC2);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
texAnotherThread.LoadFromFile1("1.jpg");
});
th.join();
//这两个参数顺序是和渲染结果有关系的
wglShareLists(hGLRC2, hGLRC); //只能这样子。 }

使用线程2来渲染,代码如下:  结果是可以显示

void MultiThreadTexture_App::Init()
{
hWnd = GetActiveWindow();
hDC = GetDC(hWnd);
hGLRC = wglGetCurrentContext();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
hGLRC2 = wglCreateContext(hDC);
wglShareLists(hGLRC, hGLRC2);
isRunning = true;
std::thread th([this]() {
wglMakeCurrent(hDC, hGLRC2);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
texAnotherThread.LoadFromFile1("1.jpg");while (isRunning) //使用程序来控制 isRunning在线程运行之前为true,程序退出为false
{
if (isRenderBegin) //在调用Render的时候为true。
{
Render(-10);
AfterRender();
}
}
});
th.detach();
} void MultiThreadTexture_App::Render(int deltaMillionSeconds)
{
if (!isRenderBegin)
isRenderBegin = true;
if (deltaMillionSeconds != -10) return;
glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, width / height, 0.1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 100, 0, 0, 0, 0, 1, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 1);
glClearDepth(1000);
glEnable(GL_FILL);
glBindTexture(GL_TEXTURE_2D, texAnotherThread.texId);
glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(1, 0); glVertex3f(100, 0, 0);
glTexCoord2f(1, 1); glVertex3f(100, 100, 0);
glTexCoord2f(0, 1); glVertex3f(0, 100, 0);
glEnd(); }

最后,做了一个交替渲染, 每1s为间隔,线程1,线程2交替渲染,而且他们使用对方的资源,比如第1s线程1渲染用的是线程2加载的纹理,第2s线程2渲染用的是线程1加载的纹理,如此循环...

代码如下:

void MultiThreadTexture_App::Init()
{
hWnd = GetActiveWindow();
hDC = GetDC(hWnd);
hGLRC = wglGetCurrentContext();
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
hGLRC2 = wglCreateContext(hDC);
wglShareLists(hGLRC, hGLRC2);
tex.LoadFromFile1("2.png");
isRunning = true;
lastRenderThreadID = -1;//默认值
std::thread th([this]() {
wglMakeCurrent(hDC, hGLRC2);
glEnable(GL_TEXTURE_2D);
glEnable(GL_DEPTH);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
texAnotherThread.LoadFromFile1("1.jpg");
while (isRunning) //使用程序来控制 isRunning在线程运行之前为true,程序退出为false
{
if (isRenderBegin) //在调用Render的时候为true。
{
Render(-10);
AfterRender();
}
}
});
th.detach(); }
//deltaMillionSeconds是根据时间变化的,每一帧的间隔
void MultiThreadTexture_App::Render(int deltaMillionSeconds)
{
mtx.lock();
if (!isRenderBegin)
isRenderBegin = true; isRenderBegin = true;
if (deltaMillionSeconds == -10)
RenderThreadID = 2;
else
RenderThreadID = 1; if (lastRenderThreadID != -1 && lastRenderThreadID == RenderThreadID)
{//和之前的线程一致
::Sleep(1000); //保证1s调用1次
mtx.unlock();
return;
} glViewport(0, 0, width, height);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, width / height, 0.1, 1000);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0, 0, 100, 0, 0, 0, 0, 1, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glClearColor(0, 0, 0, 1);
glClearDepth(1000);
glEnable(GL_FILL);
//这里互相使用对方的资源
if (RenderThreadID == 1)
glBindTexture(GL_TEXTURE_2D, texAnotherThread.texId);
else
glBindTexture(GL_TEXTURE_2D, tex.texId); glBegin(GL_QUADS);
glTexCoord2f(0, 0); glVertex3f(0, 0, 0);
glTexCoord2f(1, 0); glVertex3f(100, 0, 0);
glTexCoord2f(1, 1); glVertex3f(100, 100, 0);
glTexCoord2f(0, 1); glVertex3f(0, 100, 0);
glEnd();
lastRenderThreadID = RenderThreadID;
//休息1秒钟然后
::Sleep(1000);
mtx.unlock();
} void MultiThreadTexture_App::Release()
{
isRunning = false;
}

线程1用的是游戏截图,线程2用的是狗头。而渲染使用对方的资源,效果图如下:

openGL之多线程渲染的更多相关文章

  1. BGFX多线程渲染

    BGFX多线程渲染 1. 多线程基础 1. 并发概念 1. 并发任务简介 在多年以前,在手机.pc端.游戏机等,都是一个单核的CPU.这样,在硬件层面上,处理多个任务的时候,也是把一些任务切分成一些小 ...

  2. 《图解UE4渲染体系》Part 1 多线程渲染

    上回书<Part 0 引擎基础>说到,我们粗略地知道UE4是以哪些类来管理一个游戏场景里的数据的,但这仅仅是我们开始探索UE4渲染体系的一小步. 本回主要介绍UE4渲染体系中比较宏观顶层的 ...

  3. Unity4、Unity5移动平台多线程渲染在部分安卓手机上会造成闪退

    你看到的crash堆栈可能是这样的: SIGSEGV(SEGV_MAPERR)   #00  pc 0001276c                          /system/lib/libc ...

  4. HTML5触屏版多线程渲染模板技术分享

    前言: 了解js编译原理的屌丝们都知道,js是单线程的,想当年各路神仙为了实现js的多线程,为了解决innerHTML输出大段HTML卡页面的顽疾,纷纷设计了诸如假冒的“多线程“实现,我自己也在写开源 ...

  5. Unity3D 海水多线程渲染算法实现

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家,特邀编辑,畅销书作者,已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D实战核心技术详解 ...

  6. 通过OpenGL理解前端渲染原理(1)

    一.OpenGL OpenGL,是一套绘制3D图形的API,当然它也可以用来绘制2D的物体.OpenGL有一大套可以用来操作模型和图片的函数,通常编写OpenGL库的人是显卡的制造者.我们买的显卡都支 ...

  7. DirectX* 11 多线程渲染的性能、方法和实践

    对于在 CPU 上运行的 PC 游戏,渲染通常是主要的性能瓶颈:多线程渲染是一种消除瓶颈的有效方法.本文研究了 DirectX* 11 多线程渲染的性能可扩展性,讨论了多线程渲染的两种基本方法,并介绍 ...

  8. 还在使用OpenGL ES做渲染,你Out了,赶紧来拥抱Vulkan吧~

    背景介绍 Vulkan是Khronos组织制定的"下一代"开放的图形显示API.是与DirectX12能够匹敌的GPU API标准. Vulkan是基于AMD的Mantle API ...

  9. opengl离屏渲染(不需要和窗口绑定,仅当作一个可以渲染一张图片的API使用)+ opencv显示

    具体过程参考的是这篇BLOG: http://wiki.woodpecker.org.cn/moin/lilin/swig-glBmpContext 这一片BLOG的代码有个 BOOL SaveBmp ...

  10. OpenGL中的渲染方式—— GL_TRIANGLE_STRIP

    OpenGL值绘制三角形的方式常用的有三种,分别是GL_TRIANGLES.GL_TRIANGLE_STRIP.GL_TRIANGLE_FAN,其效果如依次是: 从左起:第一个方式是GL_TRIANG ...

随机推荐

  1. jsonp原理详解——终于弄明白了JSONP

    什么是JSONP? 其实网上关于JSONP的讲解有很多,但却千篇一律,而且云里雾里,对于很多刚接触的人来讲理解起来有些困难,着用自己的方式来阐释一下这个问题,看看是否有帮助. 1.一个众所周知的问题, ...

  2. 算法金 | 再见,支持向量机 SVM!

    大侠幸会,在下全网同名「算法金」 0 基础转 AI 上岸,多个算法赛 Top 「日更万日,让更多人享受智能乐趣」 今日 170+/10000 一.SVM概述 定义与基本概念 支持向量机(SVM)是一种 ...

  3. Rainbond 携手 TOPIAM 打造企业级云原生身份管控新体验

    TOPIAM 企业数字身份管控平台, 是一个开源的IDaas/IAM平台.用于管理账号.权限.身份认证.应用访问,帮助整合部署在本地或云端的内部办公系统.业务系统及三方 SaaS 系统的所有身份,实现 ...

  4. 获得centos7网络yum源

    获得centos73网络yum源 wget http://mirrors.163.com/.help/CentOS7-Base-163.repo 网易 wget -O /etc/yum.repos.d ...

  5. Azkaban快速入门

    先说一些废话 因为之前自己工作中有用过Azkaban作为自动化任务调度工具,所以想参考自己之前的使用经验,总结一下关于Azkaban的使用,方便大家使用Azkaban快速实现企业级自动化任务 如何选择 ...

  6. Java中可以用的大数据推荐算法

    在Java中实现大数据推荐算法时,通常会使用一些开源的机器学习库,如Apache Mahout.Weka.DL4J(DeepLearning4j,用于深度学习)或者Spark MLlib(用于在Spa ...

  7. 剑指Offer-50.数组中重复的数字(C++/Java)

    题目: 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中任意一个重复的数字. 例如,如果输入长度为7 ...

  8. tomcat部署Jenkins

    安装环境 jdk 1.8 tomcat 9.0 jenkins 2.290 准备工作 安装好Tomcat,8080端口启动 安装好jdk,配置好环境变量 ECS服务器安全组放开8080端口 关闭防火墙 ...

  9. Stable Diffusion 解析:探寻 AI 绘画背后的科技神秘

    AI 绘画发展史 在谈论 Stable Diffusion 之前,有必要先了解 AI 绘画的发展历程. 早在 2012 年,华人科学家吴恩达领导的团队训练出了当时世界上最大的深度学习网络.这个网络能够 ...

  10. word文档生成视频,自动配音、背景音乐、自动字幕,另类创作工具

    简介 不同于别的视频创作工具,这个工具创作视频只需要在word文档中打字,插入图片即可.完事后就能获得一个带有配音.字幕.背景音乐.视频特效滤镜的优美作品. 这种不要门槛,没有技术难度的视频创作工具, ...