opengl 怎么在线程使用

醉过方知酒烈 2013-07-03 12:04:16
我现在用Qt的QGLWidget,做一个opengl显示图片的界面,但是load图片和显示的过程慢,如果图片多的话,会导致主进程卡住。
我看网上有opengl多线程的方式,我想知道 QGlwidget可以在线程中处理加载和绘制的过程吗?或者模拟多线程来实现? 就是不要让主进程卡住就行了。
...全文
626 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
tdl1001 2014-09-05
  • 打赏
  • 举报
回复
发现Qt5.3上convertToGLFormat()有bug,文档写"The GL format used is GL_RGBA.",代码里用Format_ARGB32,坑爹!! 还有bindTexture内部会转Format,用了bindTexture也不需要用QPixmap了 加载改为
QImage bgImage = m_bg_image.transformed(QTransform::fromScale(1.0, -1.0)); //解决上下颠倒的问题
makeCurrent(); //没验证是不是需要,先放着
m_bg_texture = bindTexture(bgImage);
tdl1001 2014-09-05
  • 打赏
  • 举报
回复
好吧,加载改成了这样。
	makeCurrent();
	QImage bgImage = convertToGLFormat(m_bg_image); //调整为RGBA,并解决上下颠倒的问题
	QPixmap bgPixmap;
	bool su = bgPixmap.convertFromImage(bgImage); //不用QPixmap,显示白的
	m_bg_texture = bindTexture(bgPixmap);
tdl1001 2014-09-05
  • 打赏
  • 举报
回复
我也在纠结,我现在是这样的 加载代码:
	makeCurrent();
	QImage bgImage = convertToGLFormat(m_bg_image);
	glGenTextures(1, &m_bg_texture);

	glBindTexture(GL_TEXTURE_2D, m_bg_texture);
	glTexImage2D(GL_TEXTURE_2D, 0, 4, bgImage.width(), bgImage.height(), 0,
		GL_BGRA, GL_UNSIGNED_BYTE, bgImage.bits());
	glBindTexture(GL_TEXTURE_2D, 0);
显示代码:
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

	glDepthMask(false);

	QRectF rect(-0.8f, -0.8f, 1.0f, 1.0f);
	drawTexture(rect, m_bg_texture);

	glDepthMask(true);
不管原来图像里是啥,最终显示都是全白。郁闷。 不知道为什么不显示原来的颜色
uuheart 2013-07-15
  • 打赏
  • 举报
回复
借个地方,楼主的问题解决了么?
蓝色記憶 2013-07-08
  • 打赏
  • 举报
回复
QtOpengl在Qt4.8以后就开始支持多线程渲染了,在Qt4.8版本中的demos里面有一个例子,glhypnotizer,好像就是用多线程进行渲染的,楼主可以去看一下,还有去google搜一下 qt opengl multithreading吧。
醉过方知酒烈 2013-07-05
  • 打赏
  • 举报
回复
没有人会QGLWidget贴纹理吗? 就是完全使用Qt的函数,不要用opengl的方法。 求高手。
  • 打赏
  • 举报
回复
。。。。qglwidget里面不都是直接用gl的东西么。。 Qt有个opengl的教程, 是根据NEHE openggl改的。可以搜索下,有你需要的。
醉过方知酒烈 2013-07-04
  • 打赏
  • 举报
回复
引用 8 楼 jiangcaiyang123 的回复:
这里我说说我对OpenGL开发的理解。 wgl、glx、agl是不同平台下对OpenGL提供的API,在不同平台下和OpenGL API配合使用。 Qt提供了对OpenGL的封装,并且宣称能够跨平台,因此开发的时候尽量不用平台相关的代码,只用Qt提供的API。
那几行代码是后加的。 原来没有,就是因为显示不出来,才尝试一下。如果Qt自己能解决那肯定是最好不过了,你有好的方法吗?就针对我这个问题?
彩阳 2013-07-04
  • 打赏
  • 举报
回复
这里我说说我对OpenGL开发的理解。 wgl、glx、agl是不同平台下对OpenGL提供的API,在不同平台下和OpenGL API配合使用。 Qt提供了对OpenGL的封装,并且宣称能够跨平台,因此开发的时候尽量不用平台相关的代码,只用Qt提供的API。
醉过方知酒烈 2013-07-04
  • 打赏
  • 举报
回复
wglMakeCurrent(hDC, hRC1); 这几行代码是我在网上找的,说是要设置一下当前CD,但是貌似不起作用,或者是我使用的不对?
醉过方知酒烈 2013-07-04
  • 打赏
  • 举报
回复
引用 5 楼 jiangcaiyang123 的回复:
我没有看到在gluBuild2DMipmaps()函数之前调用glBindTexture(GL_TEXTURE_2D, texture[m_pageNum+1]); 啊。 图片显示不出来,只有白色这种情况,应该是没有绑定纹理(也就是绑定0纹理),而出现白色。
不好意思,是我漏掉了,有写的。 QImage tex = QGLWidget::convertToGLFormat( buf ); glBindTexture( GL_TEXTURE_2D, texture[i] ); 我就是都在主进程中使用的时候就是好的,图片也都能显示,主窗口就是继承QGLWidget。 因为我是要实时的显示图片,就是从别的窗口切换到这个界面,再去把图片加载进来。但是这一段代码需要的时间挺长,所以会卡住。 我就创建了一个线程,线程里边这么写的: LoadTexImgThread::LoadTexImgThread() :QThread() { wglMakeCurrent(hDC, hRC1); } LoadTexImgThread::~LoadTexImgThread() { } void LoadTexImgThread::run( void ) { wglMakeCurrent(hDC, hRC1); loadContentTextures(); // wglMakeCurrent(NULL, NULL); emit sigLoadImgFinish(); } void LoadTexImgThread::loadContentTextures() { QImage buf; QStringList fileList = findFiles(QString("./img")); int fileNum = fileList.size(); glGenTextures( fileNum, texture); for(int i=0;i<fileNum;i++) { bool falg = buf.load(fileList.at(i)); QImage tex = QGLWidget::convertToGLFormat( buf ); glBindTexture( GL_TEXTURE_2D, texture[i] ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST ); gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, tex.width(),tex.height(), GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() ); } // updateGL(); // emit sigLoadImgFinish(); } 结果就显示不出来了,在同一个进程中是好的。。 我的QQ是65784464,方便加一下吗?
醉过方知酒烈 2013-07-04
  • 打赏
  • 举报
回复
引用 8 楼 jiangcaiyang123 的回复:
这里我说说我对OpenGL开发的理解。 wgl、glx、agl是不同平台下对OpenGL提供的API,在不同平台下和OpenGL API配合使用。 Qt提供了对OpenGL的封装,并且宣称能够跨平台,因此开发的时候尽量不用平台相关的代码,只用Qt提供的API。
Qt是这么用吗? GLuint texture = bindTexture(QPixmap(QString("./layer.png")), GL_TEXTURE_2D); glBegin(GL_QUADS); QRectF rect(0.0f,0.0f,0.2f,0.2f); drawTexture(rect,texture,GL_TEXTURE_2D); glEnd(); 什么也画不出来啊,那个地方不对啊。
醉过方知酒烈 2013-07-04
  • 打赏
  • 举报
回复
引用 8 楼 jiangcaiyang123 的回复:
这里我说说我对OpenGL开发的理解。 wgl、glx、agl是不同平台下对OpenGL提供的API,在不同平台下和OpenGL API配合使用。 Qt提供了对OpenGL的封装,并且宣称能够跨平台,因此开发的时候尽量不用平台相关的代码,只用Qt提供的API。
你可以帮我写一个Qt下边的最简单的代码吗?就是一个线程导入图片,主进程把图片贴到一个矩形上边,可以吗? 我看了一下貌似Qt的opengl没有本来那么麻烦,但是我不知道怎么下手。
乐者明也 2013-07-04
  • 打赏
  • 举报
回复
Opengl...跨平台,不懂,倒是用过OpenTk
醉过方知酒烈 2013-07-03
  • 打赏
  • 举报
回复
沉的真快,顶下。
彩阳 2013-07-03
  • 打赏
  • 举报
回复
我没有看到在gluBuild2DMipmaps()函数之前调用glBindTexture(GL_TEXTURE_2D, texture[m_pageNum+1]); 啊。 图片显示不出来,只有白色这种情况,应该是没有绑定纹理(也就是绑定0纹理),而出现白色。
醉过方知酒烈 2013-07-03
  • 打赏
  • 举报
回复
引用 3 楼 jiangcaiyang123 的回复:
[quote=引用 2 楼 cai6811376 的回复:] @彩阳 来帮帮他
我来了。 现在经验显示,多线程只有在载入资源的时候值得使用。渲染时最好不用多线程。 可以开一个线程载入所有资源,然后显示。 不过我做的例子,还没有使用多线程载入和显示纹理。基本的够用。除非你有数十数百个图片,或者一张图片超过了一般电脑分辨率的变态的大小。 简单点用QThread来实现吧。看看相关例子,很容易就实现的。 [/quote] 我现在就是想载入一些图片,有可能会有几十张(不确定),大小就是分辨率的大小。 我是这么写的: QImage buf; QStringList fileList = findFiles(QString("./img"));//拿到图片列表 int fileNum = fileList.size(); glGenTextures( fileNum, texture); for(int i=0;i<fileNum;i++) { buf.load(fileList.at(i)); QImage tex = QGLWidget::convertToGLFormat( buf ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST ); gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGBA, tex.width(),tex.height(), GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() ); 但是上边这一段占用的时间挺长的,所以我想把他放在线程中,我就是用的QThread,但是放进去之后,图片就显示不出来的,全是白色的,我理解是最后的两句是绘制的过程,所以不能在线程中实现,但是我该怎么样来实现呢?求指点。 glBindTexture(GL_TEXTURE_2D, texture[m_pageNum+1]); glBegin(GL_QUADS); glTexCoord2f( 0.5, 1.0 );glVertex3f( 0.0, m_screenScale, 0.0 ); glTexCoord2f( 0.0, 1.0 );glVertex3f( cos(30*M_PI/180), m_screenScale, sin(30*M_PI/180)); glTexCoord2f( 0.0, 0.0 );glVertex3f( cos(30*M_PI/180),-m_screenScale,sin(30*M_PI/180)); glTexCoord2f( 0.5, 0.0 );glVertex3f( 0.0, -m_screenScale, 0.0 ); glEnd(); 我在真正绘制的时候是这么写的,速度还好。就是最初的载入很慢。
彩阳 2013-07-03
  • 打赏
  • 举报
回复
引用 2 楼 cai6811376 的回复:
@彩阳 来帮帮他
我来了。 现在经验显示,多线程只有在载入资源的时候值得使用。渲染时最好不用多线程。 可以开一个线程载入所有资源,然后显示。 不过我做的例子,还没有使用多线程载入和显示纹理。基本的够用。除非你有数十数百个图片,或者一张图片超过了一般电脑分辨率的变态的大小。 简单点用QThread来实现吧。看看相关例子,很容易就实现的。
xcyl 2013-07-03
  • 打赏
  • 举报
回复
@彩阳 来帮帮他
欢迎来到OpenGL系列教程之《OpenGL进阶》的OSX版。由于OpenGL的发展历史比较久远,因此给萌新们带来了不小的入门门槛,没有理清头绪一头扎进OpenGL里面进行学习的萌新们,可能很难理清头绪。不过不用怕,跟着我们的OpenGL系列教程一起学习,你将由浅入深的逐步掌握OpenGL的精髓,我们为萌新准备的是一套成体系的知识系统,而不是凌乱的知识碎片。你将在我们这里把OpenGL学的清清楚楚,明明白白。无论你是小白学生、还是职场员工,都可以跟着我们的教程,一步一个脚印把整个图形学领域的知识学个痛快。在正式进入学习之前,我们需要提醒同学们注意下面这些点。比起一般的教程,我们这里会让你掌握整个图形学硬件API的全貌。在学习OpenGL进阶课程之前,我们期望你最好是已经掌握了我们的OpenGL入门课程,因为在入门课程中我们会为你构建足够多的知识框架来帮助你更好的理解OpenGL进阶这边的知识点。OpenGL是一个直接与GPU接触的API,这种方便硬件操作,而且还是面向图形学编程的语言,当之无愧的要选C++。你不必担心的是,我们并不使用花里胡哨的C++语法,我们使用最基本的C With Class的编程风格,来保证程序的可移植性和可阅读性。如果你是来自其他行业的程序员,你觉得学起来难,纯粹是因为你的编程思路还是单线程的思路,算你厉害,你是个多线程思路那又如何。我们图形学编程里的程序是几百几千个线程同时运行的。怕不怕?如果你是完全没什么头绪的程序员,你的最好策略是,先把所有的视频浏览一遍,把随堂代码都拖出来编译运行一次,看看都是些什么东西。然后再第二遍精读课程。图形学编程更多的是硬件操作和数学,编程语言只是个工具和皮毛。没有高层语言那么多API让你用。如果存在,那么一定是某个个人提供的,OpenGL的API是由显卡驱动直接提供,也就是说,是显卡的硬件生产者提供了OpenGL的API,如果你的显卡是GTX1060,那么他的OpenGLAPI就是由nVidia提供的。如果你用的是Intel的集成显卡HD4600,那么他的OpenGLAPI就是由Intel提供的。如果是移动端比如Mali的GPU,那么它的OpenGLES的API就是由arm实现的。而硬件厂商提供的都是标准的C语言API,所以高层语言是不存在OpenGL的API的。

16,240

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧