2012-01-08 16 views
5

Potrzebuję przeskalować wynik obrazu glDrawPixels.Jak skalować glDrawPixels?

Rysuję bufor obrazu o rozdzielczości 640x480 pikseli z glDrawPixels w QT QGLWidget.

tryed aby wykonać następujące czynności w PaintGL:

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

Ale to nie działa.

ja ustawienie rzutni OpenGL i glOrtho z wielkością widget jak:

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 (); 
    } 

Odpowiedz

5

Brzmi jak co rzeczywiście trzeba zrobić, zamiast dzwonić glDrawPixels() jest załadowanie danych obrazu do tekstury i narysuj teksturowane kwadraty wielkości okna. Więc coś takiego:

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(); 

Albo jeśli to zbyt wiele pracy, glPixelZoom (windowWidth/640, windowHeight/480), może załatwić sprawę, too.

+0

Dziękuję bardzo muuch, mam sprawdzanie go teraz – Herman

+1

znalazłem, że muszę się glEnable/glDisable (GL_TEXTURE_RECTANGLE) para wokół początku/końca, aby uzyskać teksturę zastosowaną do quadów, i że potrzebuję użyć GL_TEXTURE_RECTANGLE bez _EXT, ale to w przeciwnym razie działało idealnie również dla mnie, dzięki! : D –

1

Muszę przeskalować wynik obrazu glDrawPixels.

glDrawPixels bezpośrednio przechodzi do bufora ramki. Więc każdy przychodzący piksel jest mapowany 1: 1 na wyjście. Jest funkcja (ach, dlaczego ci to mówię) glPixelZoom, która pozwala na powiększenie glDrawPixels.

ALE nalegam, aby nie używać programu glDrawPixels!

Zamiast tego używaj quadów tekstur. glDrawPixels to amortyzowana funkcja, nie obsługiwana już przez nowoczesny OpenGL-3. Nawet jeśli nie był przestarzały, nadal jest bardzo powolną funkcją. Teksturowane quady są lepsze pod każdym względem.

+0

OK, sprawdzę to, naprawdę doceniam twoją pomoc. Będę chaange do tekstury – Herman

+0

@ datenwolf jak mogę uzyskać bezpośredni dostęp do bufora ramki? Chcę narysować wybrany przeze mnie bufor 2d w czasie rzeczywistym, używając EGL jako miłego proxy przyspieszenia sprzętowego. Czy tekstury nadają się do tego? –

+1

@ rr-: OpenGL nie daje ci bezpośredniego (jak przy podawaniu wskaźnika do pamięci bufora ramki) do zapisu. Również ze względów wydajnościowych należy unikać bezpośrednich zapisów. Chcesz asynchronicznie zapisywać do bufora ramki. I używając dowolnego wariantu OpenGL, robi się to poprzez załadowanie obrazu do tekstury i jest poleceniem rysowania dla teksturowanego kwadratu. Komenda jest ustawiana w kolejce i wykonywana asynchronicznie, tak że procesor nie jest zatrzymywany przez żadne zdarzenia graficzne, na które musiał czekać. – datenwolf

2

Tylko dla dalszego odniesienia: Zamiast robić glScalef(windowWidth/640, windowHeight/480, 0); przed glDrawPixels należy zrobić zoom pikseli:

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); 
Powiązane problemy