2010-02-05 15 views
5

Este es mi código que utilizo para conseguir mi posición del ratón en la escena 3D:glReadPixels() realmente una solución lenta y mejor para obtener las coordenadas de OpenGL desde la posición del mouse?

void GetOGLPos(int x, int y, GLdouble &pX, GLdouble &pY, GLdouble &pZ){ 
GLint viewport[4]; 
GLdouble modelview[16]; 
GLdouble projection[16]; 
GLfloat winX, winY, winZ; 

glGetDoublev(GL_MODELVIEW_MATRIX, modelview); 
glGetDoublev(GL_PROJECTION_MATRIX, projection); 
glGetIntegerv(GL_VIEWPORT, viewport); 

winX = (float)x; 
winY = (float)viewport[3]-(float)y; 
glReadPixels(x, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); 

gluUnProject(winX, winY, winZ, modelview, projection, viewport, &pX, &pY, &pZ); 
} 

Pero me di cuenta de una cosa mala ... 1-2 llamadas a esa función por cuadro hace uso de la CPU al 100%, 3 o más llamadas 200% de uso de CPU (tengo 4 núcleos, 1-2 llamadas = 25%, 3 o más llamadas = 50%, no puedo superar el 50%, creo ...)

Es Hay alguna otra forma de hacer esto de manera eficiente? Estoy usando 4 llamadas a esa función en cada cuadro, así que sé qué áreas debo representar para mi escena (las tomo de cada esquina de la pantalla).

También uso esto para saber a qué lugar estoy apuntando con el mouse, por lo que lo necesito en tiempo real, pero me gustaría usar menos CPU, porque incluso solo 1 llamada hace que sea 100% de uso para sistemas single core.

EDITAR

He intentado método glPushName(), pero es incluso más lenta, más probablemente más lento en mi GPU que en la CPU. Además, mi uso de CPU es solo de 0-1% cuando no uso una sola llamada glReadPixels() en mi programa. Lo extraño es que obtengo un uso elevado de la CPU, pero no hace que el programa se quede rezagado como se esperaría con el 100% de uso ... solo aparece el problema cuando uso otros programas mientras mi programa está encendido, entonces es lento para usarlos .

Respuesta

1

Parece que intenta hacer picking en OpenGL.

Salida este tutorial, debe venir con menos pérdida de rendimiento que su enfoque: http://gpwiki.org/index.php/OpenGL:Tutorials:Picking

Este lugar menciona otras formas de hacer picking en OpenGL: http://www.opengl.org/resources/faq/technical/selection.htm

+0

ive intenté el método glPushName(), es incluso más lento. de hecho, creo que no usa CPU, pero mi GPU, y obtengo 10fps en lugar de 500 fps ... – Newbie

+0

ten en cuenta que no selecciono solo 3 objetos posibles, tengo una cantidad ilimitada de objetos posibles ... – Newbie

+0

Agregué otro enlace acerca seleccionando GL y cómo abordarlo Espero que encuentre algo útil allí. – Laserallan

0

¿Estás absolutamente seguro de que es esa sola función que causa el problema? ¿Has probado una herramienta de perfil para confirmar? No es que quiera dudar de ti, solo quiero que estés seguro antes de pasar por el problema de depurar o cambiar grandes partes de tu código.

Estoy bastante sorprendido de que una llamada de OpenGL (para leer un píxel, nada menos) esté ocupando CPU vez. En todo caso, creo que mostraría 0 uso de CPU pero tiene un framerate lento. Pero, apenas sé lo suficiente sobre OpenGL para sospechar que hay algo realmente malo en esto. Parece poco intuitivo, supongo.

A forum post sobre el rendimiento de glReadPixels sugiere que ciertas tarjetas gráficas (especialmente las más antiguas) son simplemente muy ineficientes para mover datos de la GPU a la CPU. ¿Puede ejecutar su código en otra computadora para ver si es solo su tarjeta de video? Esta sería la mejor manera de comenzar, especialmente si tiene una tarjeta ATI y la ejecuta en la tarjeta NVIDIA de un amigo, o viceversa.

La publicación también menciona que el tipo de datos podría marcar la diferencia. No lo veo haciendo una gran diferencia, pero quién sabe.

Una cosa más que puede probar: si llama a la función cuatro veces consecutivas, tiene tres conjuntos extra innecesarios de llamadas para leer las matrices actuales. Considere tomar las matrices a través de parámetros en su lugar. Pero, dudo que glGetDoublev/glGetIntegerv esté realmente tomando mucho tiempo.

Dependiendo de lo que esté haciendo, también, es posible que desee leer sobre el sacrificio frustrado.Esto suena como lo que intenta hacer al obtener las cuatro esquinas de la pantalla. Puede ser menos costoso para usted implementar las matemáticas usted mismo en lugar de usar glUnProject.

+1

Sí, probé con y sin la función glReadPixels(), y esa función fue la causa de la lentitud. No estoy seguro sobre el uso de la CPU, es posible que solo mi modelo de CPU tenga este problema. Voy por la esquina 4 trabajando más eficientemente cuando eliminé por completo la llamada a glReadPixels(), no sé cómo funciona, pero funciona jajaja. Sí, también estaba pensando que podía calcular el rectángulo de la zona de visión, pero no sé por dónde empezar, y parece que funciona bastante bien. – Newbie

0

glReadPixels utilizará la CPU para convertir los datos leídos del framebuffer incluso cuando intenta utilizar PBO. Por ejemplo, si intenta leer datos de color por PBO, solo cuando configure param en GL_BGRA, la función no realizará conversiones y regresará inmediatamente. De lo contrario, si configura param en GL_RGBA, el uso de la CPU estará ocupado. También estoy tratando de leer datos de profundidad de framebuffer, pero glReadPixels definitivamente convertirá los datos de cualquier configuración de parámetro

Cuestiones relacionadas