2012-01-08 26 views
5

Necesito escalar el resultado de la imagen glDrawPixels.Cómo escalar glDrawPixels?

Estoy dibujando un búfer de imagen de 640x480 píxeles con glDrawPixels en un Qt QGLWidget.

He probado a hacer lo siguiente en PaintGL:

glScalef(windowWidth/640, windowHeight/480, 0); 
glDrawPixels(640,480,GL_RGB,GL_UNSIGNED_BYTE,frame); 

Pero no funciona.

estoy fijando la ventana gráfica OpenGL y glOrtho con el tamaño del widget como:

void WdtRGB::paintGL() { 

     glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

     // Setup the OpenGL viewpoint 
     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 
     glOrtho(0, windowWidth, windowHeight, 0, -1.0, 1.0); 

    glDepthMask(0); 
     //glRasterPos2i(0, 0); 
     glScalef(windowWidth/640, windowHeight/480, 0); 
     glDrawPixels(640,480,GL_RGB,GL_UNSIGNED_BYTE,frame); 
    } 

    //where windowWidth and windowHeight corresponds to the widget size. 
    /the init functions are: 

    void WdtRGB::initializeGL() { 

     glClearColor (0.8, 0.8, 0.8, 0.0); // Background to a grey tone 

     /* initialize viewing values */ 
     glMatrixMode(GL_PROJECTION); 
     glLoadIdentity(); 

     glOrtho(0, windowWidth, windowHeight, 0, -1.0, 1.0); 

     glEnable (GL_DEPTH_TEST); 

    } 

    void WdtRGB::resizeGL(int w, int h) { 
     float aspect=(float)w/(float)h; 

     windowWidth = w; 
     windowHeight = h; 
     glViewport (0, 0, (GLsizei) w, (GLsizei) h); 
     glMatrixMode (GL_PROJECTION); 
     glLoadIdentity(); 

     if(w <= h) 
       glOrtho (-5.0, 5.0, -5.0/aspect, 5.0/aspect, -5.0, 5.0); 
     else 
       glOrtho (-5.0*aspect, 5.0*aspect, -5.0, 5.0, -5.0, 5.0); 

     //printf("\nresize"); 
     emit changeSize (); 
    } 

Respuesta

5

Suena como lo que realmente tiene que hacer en lugar de llamar glDrawPixels() es para cargar los datos de imagen en una textura y dibuja un cuadrante texturizado del tamaño de la ventana. Así que algo como esto:

glGenTextures (1, &texID); 
glBindTextures (GL_TEXTURE_RECTANGLE_EXT, texID); 
glTexImage2D (GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, 640, 480, 0, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, frame); 
glBegin (GL_QUADS); 
glTexCoord2f (0, 0); 
glVertex2f (0, 0); 
glTexCoord2f (640, 0); 
glVertex2f (windowWidth, 0); 
glTexCoord2f (640, 480); 
glVertex2f (windowWidth, windowHeight); 
glTexCoord2f (0, 480); 
glVertex2f (0, windowHeight); 
glEnd(); 

O si eso es demasiado trabajo, glPixelZoom (WindowWidth/640, WindowHeight/480), podría hacer el truco, también.

+0

Muchas gracias muuch, estoy comprobando ahora mismo – Herman

+1

me pareció que necesitaba un glEnable/glDisable (GL_TEXTURE_RECTANGLE) par alrededor del comienzo/final para obtener la textura aplicada a los cuatriciclos, y que necesitaba usar GL_TEXTURE_RECTANGLE sin el _EXT, pero esto también funcionó perfectamente para mí también, ¡gracias! : D –

1

Necesito escalar el resultado de la imagen glDrawPixels.

glDrawPixels va directamente al framebuffer. Por lo tanto, cada píxel entrante se mapea 1: 1 a la salida. Hay una función (ah, ¿por qué le digo esto?) glPixelZoom, que le permite acercar glDrawPixels.

¡PERO le insto, no para usar glDrawPixels!

Use texturas cuádruples en su lugar. glDrawPixels es una función depreciada, que ya no es compatible con el OpenGL-3 moderno. E incluso cuando no estaba en desuso todavía es una función muy lenta. Los cuádriceps con textura son mejores en todos los aspectos.

+0

Ok, voy a comprobarlo, realmente aprecio su ayuda. Iré a las texturas – Herman

+0

@datenwolf ¿cómo puedo acceder al frame buffer directamente? Quiero dibujar un buffer 2d de mi elección en tiempo real, usando EGL como un buen proxy para la aceleración de hardware. ¿Son las texturas adecuadas para esto? –

+1

@ rr-: OpenGL no le da acceso directo (como al darle un puntero a la memoria de framebuffer) para escribir. También por razones de eficiencia, se deben evitar las escrituras directas. Desea escribir asincrónicamente en el framebuffer. Y al utilizar cualquier variante de OpenGL, esto se hace cargando su imagen en una textura y emitiendo un comando de dibujo para un quad texturizado. El comando se pone en cola y se ejecuta de forma asíncrona, de modo que su proceso de CPU no se detiene por ningún evento de gráficos que haya tenido que esperar. – datenwolf

2

Sólo para mayor referencia: En vez de hacer el glScalef(windowWidth/640, windowHeight/480, 0); antes de la glDrawPixels que debe hacer un zoom de píxeles:

glRasterPos2i(0,0); 
GLint iViewport[4]; 
glGetIntegerv(GL_VIEWPORT, iViewport); 
glPixelZoom(iViewport[2]/640, iViewport[3]/480); 
glDrawPixels(640,480,GL_RGB,GL_UNSIGNED_BYTE,frame);