Cómo ejecutar opengl en qt
Puede ejecutar opengl desde QGLWidget, que hereda de QWidget y puede llamar directamente a la interfaz opengl. Esto se describe en la documentación de qt
y hay ejemplos, por lo que no entraré en detalles. Pero esto no se puede hacer en software formal. Porque el software oficial usa la clase de escena QGraphicsScene para manipular y operar todos los elementos
y usa QGraphicsView para mostrar, y cada elemento es una subclase de QGraphicsItem. QGLWidget no es una clase QGraphicsItem, intenté usar un QGLWidget normal en lugar de una clase QGraphicsItem, intenté agregar un QGraphicsItem a través de un proxy como una clase QWidget normal, pero sin éxito. Quizás haya una manera de hacer esto, pero no puedo encontrarla.
Por lo tanto, dejé de intentar usar QGLWidget para operar opengl y, en su lugar, busqué una forma de operar opengl directamente en QGraphicsItem. Al mirar la documentación y el código de muestra, encontré este método:
1 Agregue opengl y la biblioteca correspondiente en el archivo del proyecto qt.
2
Utilice el siguiente código para especificar un cuadro de diálogo 3D para QGraphicsView:
QGLWidget *widget = new
QGLWidget(QGLFormat (QGL: :SampleBuffers));
widget->makeCurrent();
QGraphicsView
ver;
view.setViewport( widget);
El código anterior le dice a la clase QGraphicsView que el objeto dibujado actualmente tiene opengl habilitado. Por lo tanto, todos los elementos de la escena se dibujarán en el widget.
3
Escriba una clase de herencia para QGraphicsItem, especialmente sobrecargue la función de pintura. El código es el siguiente:
void XXX::paint(QPainter
*painter, const QStyleOptionGraphicsItem *option, QWidget
*widget)
{
pintor->beginNativePainting();
glColor3f(0.5,1.0,0.2);
glBegin(GL_TRIANGLES);
glVertex3f(100.
glVertex3f(100.0,100.0,-100.0);
glVertex3f(150.0, 100.0,
-100.0); p>
glVertex3f(100.0, 150.0,
-100.0);
glEnd();
pintor->. endNativePainting(); p>
}
La función anterior utiliza principalmente la interfaz opengl para dibujar triángulos. Recuerde ejecutar siempre las instrucciones pintor->beginNativePainting() y pintor->endNativePainting() antes de dibujar opengl.
La relación entre QGraphicsScene,
QGraphicsView y QGraphicsItem se puede encontrar en la documentación y no se describirá nuevamente.
Pero el triángulo que dibujé usando este método no se mostró en la ventana. Encontré el problema en la función QGraphicsItem::boundingRect(). Esta función es
¿Qué hace? Esta función se utiliza principalmente para devolver el tamaño inicial del elemento, que no cambiará fácilmente. Se pueden realizar cambios posteriores a través de la matriz, pero el tamaño inicial permanece sin cambios. QGraphicsView usa el rectángulo para determinar si es necesario volver a dibujar el elemento actual. Si está fuera del área de volver a dibujar, no se llamará a la función de volver a dibujar. Si está fuera del área de redibujo, no se llamará a la función de redibujo. Al mismo tiempo, la detección de colisiones, etc. también se puede juzgar utilizando este rectángulo. Resulta que el envoltorio de matriz del proyecto en sí es incorrecto, por lo que no se puede volver a dibujar, por lo que modificarlo es correcto.
El contenido anterior es bastante descuidado, por lo que no entraré en detalles sobre cómo cambiarlo. Para dibujar correctamente, debe descubrir la relación entre el sistema de coordenadas, QGraphicsScene, QGraphicsView y QGraphicsItem. Leí la documentación y la probé yo mismo, pero siento que existen algunas discrepancias entre la documentación y los resultados de la prueba. No quiero hablar de diferencias específicas. No hablaré de las diferencias específicas.
En primer lugar, al menos según mis pruebas, el tamaño y la longitud de todo lo involucrado son claramente píxeles.
Al construir el objeto QGraphicsScene
, hay un constructor de rectángulo. ¿Qué significa este rectángulo? Después de la prueba, descubrí que este rectángulo no especifica la posición de la ventana emergente. Por ejemplo, si especifico la esquina superior izquierda del rectángulo como -1000, -1000, entonces la posición mostrada es 1000,1000. la longitud también está especificada correctamente (por supuesto, puede haber barras de desplazamiento). Por lo tanto, el punto de la esquina superior izquierda del rectángulo no es la posición de la ventana
mostrada, sino su punto lógico de la esquina superior izquierda. Todos los ARTÍCULOS que mostramos se trazan en este sistema de coordenadas lógico. Por ejemplo, si la posición de la esquina superior izquierda es -1000, -1000 y la posición del elemento es -500, -500, entonces -500, -500 equivale a 500 hacia abajo desde el Esquina superior izquierda de la ventana de visualización. La posición de las coordenadas del píxel.
Entonces, ¿qué significa el límite delimitador de QGraphicsItem? ¿Cuáles son las dimensiones devueltas? ¿En qué sistema de coordenadas se muestran las dimensiones? Primero, la unidad de tamaño debe ser píxeles y, segundo, las coordenadas del rectángulo son las coordenadas lógicas de QGraphicsScene. Por supuesto, este tamaño es el tamaño sin superposición de matriz. El rectángulo real puede cambiar después de la superposición de la matriz. Si la esquina superior izquierda del rectángulo se especifica como 100,100 en el rectángulo delimitador, entonces la posición reflejada final es la posición de las coordenadas lógicas de QGraphicsScene 100,100, si la esquina superior izquierda de QGraphicsScene se especifica como -1000,-1000, entonces la posición; es en realidad la esquina superior izquierda de la ventana La posición comienza desde 1100,1100 puntos (no necesariamente esta longitud debido a la barra de desplazamiento).
Entonces, ¿qué coordenadas utiliza la función de pintura QGraphicsItem en el dibujo de OpenGL? De hecho, también se utilizan las coordenadas lógicas de QGraphicsScene
. Como en el ejemplo anterior, el vértice en ángulo recto del triángulo rectángulo dibujado es 0,0, entonces la posición mostrada es 1000,1000 desde la esquina superior izquierda de la ventana de visualización. Sin embargo, todos los dibujos
en opengl no se basan en la superposición de matriz, por lo que si se utiliza la superposición de matriz, la posición mostrada debe ser diferente de la posición especificada. Por ejemplo, uso setPos para forzar una posición que se superpondrá a las coordenadas de los gráficos opengl y finalmente se mostrará en la ventana. Especulo que setPos en realidad está cambiando la matriz, es decir, traduciéndola.