2010-11-30 20 views
9

Muchos de ustedes usuarios de Qt (4.6 específicamente) estarán familiarizados con el ejemplo de Overpainting proporcionado en los tutoriales de OpenGL, estoy tratando de hacer algo muy similar pero usando sombreadores para OpenGL puro datos, en lugar de la antigua tubería de función fija.Uso de QPainter sobre OpenGL en QGLWidget al utilizar sombreadores

// Set background and state. 
makeCurrent(); 
qglClearColor(bgColour_); 

glEnable(GL_DEPTH_TEST); 
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); 

if (smoothLines_) { 
    glEnable(GL_BLEND); 
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 
    glEnable(GL_LINE_SMOOTH); 
    glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); 
} 

// Clear the buffers. 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glUseProgram(shader_); 

// Draw the grid. 
try { 
    glLineWidth(2.0f); 
    manager_->setColour(centreColour_); 
    grid_->draw(oE_GLGrid::Centre); 

    glLineWidth(1.5f); 
    manager_->setColour(majorColour_); 
    grid_->draw(oE_GLGrid::Major); 

    glLineWidth(1.0f); 
    manager_->setColour(minorColour_); 
    grid_->draw(oE_GLGrid::Minor); 
} catch(oE_GLException& e) { 
    cout << "OpenGL Error: " << e.what() << endl; 
    return; 
} 

// Reset OpenGL state for overlays. 
glDisable(GL_DEPTH_TEST); 
if (smoothLines_) { 
    glDisable(GL_BLEND); 
    glDisable(GL_LINE_SMOOTH); 
} 

// Draw the overlays. 
QPainter p(this); 
p.beginNativePainting(); 
p.fillRect(10, 10, 100, 100, 
     QColor(255, 0, 0)); 
p.endNativePainting(); 

Estoy construyendo una aplicación de activos en 3D, por lo tanto, las cosas de la grilla. Para que sea realmente obvio cuando funciona, debe aparecer un gran rectángulo rojo en la esquina superior izquierda del widget, pero no es así.

El 3D funciona bien, pero QPainter no obtiene nada en la pantalla. La única diferencia real que puedo ver entre el mío y los documentos es que todos los cálculos de la matriz de proyección y transformación están escondidos en otras funciones y luego se cargan en el sombreador a través de glUniform. Presumiblemente, como QPainter divide los activos en 2D en triángulos, esto significa que los sombreadores de QPainter no tienen acceso a mis matrices de proyección/transformación, por lo que mi triángulo rojo comienza a dibujarse, pero quizás en algún lugar fuera de la pantalla.

Respuesta

10

Llame a beginNativePainting() antes de realizar llamadas OpenGL. Un glPush/Pop del estado OpenGL también puede ser necesario. Pruebe algo como lo siguiente:

QPainter p(this); 
p.beginNativePainting(); 

// Maybe necessary 
glPushAttrib(GL_ALL_ATTRIB_BITS); 
glMatrixMode(GL_PROJECTION); 
glPushMatrix(); 
glMatrixMode(GL_MODELVIEW); 
glPushMatrix(); 

// Put OpenGL code here 

// Necessary if used glPush-es above 
glMatrixMode(GL_PROJECTION); 
glPopMatrix(); 
glMatrixMode(GL_MODELVIEW); 
glPopMatrix(); 
glPopAttrib(); 

p.endNativePainting(); 

p.fillRect(10, 10, 100, 100, 
     QColor(255, 0, 0)); 
+0

Todavía no hay suerte, los datos 3D se ve afectado, pero no parece que los datos QPainter. Me pregunto si será más rápido/más fácil renderizar en un búfer de píxeles, cargarlo en un QPainter como un mapa de fondo, y luego 'pintar' en la parte superior antes de dibujar en la pantalla. ¿O es mucho más lento de lo que parece? – cmannett85

+0

¿Aparecen los datos de QPainter si no realiza el dibujo en 3D? – baysmith

+0

Rellené la función paintEvent() solo con las llamadas a QPainter (como en el ejemplo de pintura 2D en los documentos) y no aparece nada en la pantalla, excepto que el widget se rellena en negro. – cmannett85

1

Quiero poner esta respuesta a reforzar y aclarar lo que considero como la verdadera solución, que se encuentra por cmannet85 (Comentario a responder por baysmith arriba), que consiste en limpiar los enlaces del buffer de vértices de OpenGL antes de llamar al código de QPainter.

Tuve un problema casi idéntico, en el que necesitaba cambiar entre el uso de funciones de QPainter y las funciones de OpenGL. Como se descubrió en cmannet85, una de las causas es que si las funciones de OpenGL dejan atrás los búfers de vértices atados, interfieren con el uso de OpenGL de QPainter.

I fue capaz de solucionar el problema mediante la adición de esta declaración al final de todas las partes de mi OpenGL ES código 2.0 que llaman glBindBuffer:

glBindBuffer(GL_ARRAY_BUFFER,0); 

Un segundo parámetro de 0 desenlaza el búfer.

No hubo necesidad de ningún otro cambio, como la adición de llamadas a beginNativePainting ... endNativePainting, etc.

Cuestiones relacionadas