OpenGL多线程创建纹理,附加我的测试结果

关于这个问题以前只知道多个线程不能同时使用一个RC,结果为了能动态加载,当初还做了一个通过拆分主线程的工作来模拟多线程加载的伪多线程程序,今天突然很想把这个问题彻底搞明白,结果从百度到google.com最后才在终于找到这么一篇讲解详细的英文文章,可怜我4级都没过的英语啊...

这是英文原文地址:http://veelck.wordpress.com/2008/11/28/multithread-texture-loading-in-opengl/

老外写东西一般废话会比较多,为了节省技术人员的宝贵时间就不逐句翻译了,提取一下要点吧,如下:

首先使用同一个DC创建两个RC,并且使用wglShareLists共享两个RC的资源。建议不要给这三个函数之间加其他向RC中添加东西的GL函数。

HGLRC hRC1 = wglCreateContext(hDC);

HGLRC hRC2 = wglCreateContext(hDC);

wglShareLists(hRC2, hRC1);

注意:wglShareLists的第一个参数中的RC是分享别人资源的,第二个参数中的RC是奉献资源供别人分享的。

//这是一个用来渲染场景的线程(也可用主线程来渲染)

renderingThread()

{

//...

wglMakeCurrent(hDC, hRC1);

//...

}

理论上来讲,可以在多创建几个RC,然后用多线程同时渲染。但是据说这样做是可行但却无益的。因为OpenGL会进行一些频繁的切换,导致产生高昂的开销。

//这是一个用来加载资源的线程,可以加载图片,并使用创建纹理,设置纹理参数等。

loadingThread()

{

//...

wglMakeCurrent(hDC, hRC2);

//...

}

注意,加载工作也可以写在多个线程中,例如使用多个线程从硬盘中读取图片文件(在多核机器上用双核读图片会比单核快一些),然后使用一个专门的线程调用GL的函数来创建纹理。但是,如果使用一些开源的图像库来读取图片的话就要注意了,有些开源的图像库不支持多线程,如DevIL。(FreeImage记得也存在这个问题)

最后别忘了在各个线程结束时调用wglMakeCurrent(NULL, NULL);取消DC与RC的关联。

还有要删除RC

wglDeleteContext(hRC2);

wglDeleteContext(hRC1);

最后要发一下牢骚。网上三维图形方面的资料相比其他计算机技术而言实在是不多,而且大多数还没有用。国内更是少的可怜,可能高人们都在忙着为买房子而奋斗导致没时间上网了。以下是该英文文章作者的感言,深有同感啊,向这种有国际主义精神的高人致敬。

It was quite a struggle to find anything useful in the web, only some minor things at few forums and mailing groups. But using that with some thinking and reading between lines I finally found the solution I’d like to share, as it can save (in my opinion) much time of searching and experimenting for others.

 

///

我的测试:

测试程序由nehe的lesson7项目修改完成

#include<process.h>

HDC   hDC=NULL;  // Private GDI Device Context
HGLRC  hRC=NULL;  // Permanent Rendering Context

HGLRC  hRCShareing=NULL;// 用于分享hRC的资源

 

if (!(hRC=wglCreateContext(hDC)))    // Are We Able To Get A Rendering Context?
 {
  KillGLWindow();        // Reset The Display
  MessageBox(NULL,"Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
  return FALSE;        // Return FALSE
 }

 hRCShareing = wglCreateContext(hDC);

 wglShareLists(hRCShareing, hRC);

 // 启动加载线程
 _beginthread(TextureLoadingThread, NULL, NULL);  //开启加载纹理线程

 

void TextureLoadingThread(void* p)
{

 //...

 wglMakeCurrent(hDC, hRCShareing);

 if (!LoadGLTextures())        // Jump To Texture Loading Routine
 {
  return;         // If Texture Didn't Load Return FALSE
 }

 //...

 wglMakeCurrent(NULL, NULL);

 

// 结束线程  
  _endthread();
}

 

测试结果:

通过OK,纹理显示正常

如果注释掉下面共享hrc的代码,如下所示

//wglShareLists(hRCShareing, hRC);

则纹理无法显示,看到的是个白块。

 

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

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


相关文章:

  • Rpm另类用法加固Linux安全
  • Linux下gcc与g++用法以及编写makefile
  • APE代码解读系列(四)
  • 中电信总工:我国将在2011底出现IP短缺
  • ERP:“造势”,还是“做事”
  • 我的时间哪里去了?
  • 网站投票程序
  • 凤凰岭游记(二)
  • opennms安装心得
  • Silverlight 4 tools
  • [日志]说一个人长的丑!如何说?
  • 进口食品加盟 选择自由自在休闲食品
  • Windows2008之文件服务器资源管理器
  • 硬盘安装Windows 7
  • SQL Server中SMO备份数据库进度条不显示?
  • linux 小知识
  • Linux 远程登录telnet和ssh
  • 高效单体测试
  • 错误了鹿群
  • U890第二次开发的BOM表工具--自主知识产权
  • 晓月antivirV8P绿色汉化扫描自由版
  • CentOS 5.4安装rar
  • CentOS+Subversion 配置Linux 下 SVN服务器
  • 上司最讨厌的九种人
  • C语言的数据类型→字符型数据
  • 一道数学题引发的世界动荡
  • 深入Linux文件系统
  • IE6 PNG 透明
  • 启动博客,坚持下去
  • Oracle与Google两IT巨头战争冲击整个硅谷
  • Humidex--POJ 3299
  • memcached全面剖析–memcached的删除机制和发展方向
  • 《Java并发编程实践》学习笔记之二:线程安全性(thread-safe)
  • 孙鑫mfc学习笔记第十二课
  • snmp 设置问题
  • 第五章 字符串字面量---一个特殊的数组
  • Gartner报告:2010年全球安全软件市场增长11%
  • 通过编程方式在InfoPath 2010表单的下拉框修改事件中获取数据
  • 找出最耗资源的sql ----没明白
  • Hibernate插入、查询、删除操作 HQL (转)
  • 多样化实现Windows Phone 7本地数据库访问1
  • 推荐我的一本新作:《Linux安全技术内幕》
  • 关于 Backup Exec 中的介质
  • 构建大型关系数据仓库的十大最佳实践
  • 偷懒才能编程序——计算机达人成长之路(18)
  • 关于Cluster 脑裂的文章
  • awk基础笔记
  • [原]工欲善其事,必先利其器,记一次处理Oracle Listener挂掉的处理过程
  • 这年头
  • “国际通信展”十年的印记