2011-08-23 9 views
5

Tengo un proceso que está haciendo algunas pesadas matemáticas con gl en lugar de la CPU (gl/gpu hasta ahora es aproximadamente 100 veces más rápido que cpu) pero todavía es aproximadamente un minuto para el problema habitual tamaños para estar listo, así que quería una buena barra de progreso para saber cuánto tiempo tomará.Mostrando el progreso de los cálculos gl en qt

Así que configuré mis clases para heredar desde QObject y tengo una señal currentProgress(int) que se emite de vez en cuando. Desafortunadamente, mi programa se congela durante el cálculo, por lo que no hay ningún progreso visible. Encontré la solución al llamar al QCoreApplication::processEvents(), lo que me dio otro problema. Durante esta llamada, se desencadena un repintado de toda la ventana, lo que da lugar a que mi cálculo sea invocado en una recursión infinita, ya que se desencadena por el evento paint.

Ahora todos estos problemas son señales que le dicen a mi ranura de intuición de programación que probablemente haya diseñado mal algo, así que le pregunto ¿cuál es la forma predeterminada de tener una refrescante barra de progreso en qt?

También tenga en cuenta: Cuando deseo insertar el cálculo en otro subproceso, probablemente necesite crear un nuevo contexto GL o al menos mover el existente. Entonces, si ese es el camino a seguir, ¿alguien podría explicarme cómo lograr esto en qt?

EDITAR

Para hacer las cosas más claro que no estoy dibujando a la QGLWidget pero utilizando un FBO. Probablemente sea lo mejor utilizar un contexto propio para los cálculos, pero no sé si es el camino correcto a seguir.

Nueva información

así que traté de seguir su consejo, pero tropezaron con un problema. A QGLContext parece haber estado conectado a una pantalla/objeto GUI por lo que no puedo crear una fuera de pantalla.

Además, no puedo hacer que la corriente QGLWidget esté en los otros hilos. Devuelve el error QGLContext::makeCurrent(): Failed. Además, todas las entradas sobre las que leí eran personas con el mismo problema que yo: querían hacer representaciones en otro hilo y no encontraron una solución.

Respuesta

3

Durante esta llamada, se desencadena un repintado de toda la ventana, lo que hace que mi cálculo sea invocado en una recursión infinita, ya que se desencadena por el evento paint.

Entonces no deberías estar desencadenando tus cálculos en el evento de pintura. Si la ventana es la ventana de OpenGL (es decir: el material de GPGPU se renderiza en la ventana), entonces debe ocultarlo mientras duren los cálculos. Si no es la ventana de OpenGL, actualizarla no debería provocar los cálculos.

A menos que esté utilizando OpenGL para dibujar algo, debe utilizar un destino de procesamiento fuera de la pantalla. Básicamente, usted crea una ventana GL, luego crea un nuevo contexto que comparte objetos con eso usando WGL_ARB_pbuffers (o el equivalente GLX, dependiendo de su sistema GUI). Este es un destino de renderizado fuera de la pantalla. Entonces destruyes la ventana original.

En cuanto a enhebrar, no lo olvide: incluso si tiene dos contextos GL, solo tiene una GPU. Entonces, si usa OpenGL para dibujar en una ventana y OpenGL para hacer algunos cálculos, es posible que esto no funcione.

+0

Tiene razón sobre la recursión, era la razón principal para preguntar, aunque sabía cuál sería la respuesta. Pero la forma en que describes no suena demasiado para mí. También tenga en cuenta que todos mis cálculos están fuera de la pantalla ya que edité en mi pregunta. – Nobody

+0

@ Nadie ¿Por qué no debería ser esto independiente de la plataforma, teniendo en cuenta que Qt incluso tiene una clase para la gestión de pbuffer ('QGLPixelBuffer')? –

+0

@Christian: A habló sobre las funciones wgl que son específicas de Windows. También vi la clase de QT, pero también necesita un contexto actual en su hilo, pero no termino el contexto. – Nobody

2

Sí, poner esto en un hilo propio es el camino a seguir. QGLWidget proporciona las siguientes funciones de miembro:

void QGLWidget::makeCurrent() 
void QGLWidget::doneCurrent() 

Llámalos del subproceso de procesamiento de forma adecuada. setUpdatesEnables(false); impide el procesamiento de señal habitual para desencadenar un redibujado.

BTW: ¿Te conozco del grupo de noticias comp.graphics.api.opengl? Hay un "Nadie" activo allí, también. Eche un vistazo a mi perfil de usuario para saber quién soy.

+0

Parece una solución, lo intentaré. Pero como soy nuevo en QT, la siguiente pregunta para mí es: ¿cómo genero los cálculos en un hilo separado? Offtopic: Hasta donde sé, no estoy en este grupo de noticias, pero ¿quién sabe qué está haciendo mi gemelo malvado? ^^ – Nobody

+0

@ Nadie: Derive de QTread una clase que toma un puntero a la instancia de QGLWidget en el constructor. En la función de miembro run() del hilo invoque glwidget-> makeCurrent(); haz tu procesamiento y termina con un glwidget-> doneCurrent(); – datenwolf

+0

@ Nadie: Nicol Bolas sugirió usar un PBuffer. Si los PBuffers están disponibles, yo también lo diría. – datenwolf

Cuestiones relacionadas