2014-02-05 84 views
0

我有一個PyQt應用程序,其中QtOpenGL.QGLWidget顯示一個風力渦輪機。從高分辨率的opengl(pyqt)保存圖像:

我想渦輪保存爲高resulution的圖像,但到目前爲止,我只能夠保存渲染的屏幕圖像,也就是在我的情況下1680×1050減去邊框,工具欄等

glPixelStorei(GL_PACK_ALIGNMENT, 1) 
data = glReadPixels(0, 0, self.width, self.height, GL_RGBA, GL_UNSIGNED_BYTE) 

我怎樣才能解決這個限制?

編輯

我一直在使用一個幀緩衝區試過,

from __future__ import division 
import OpenGL 
from OpenGL.GL import * 
from OpenGL.GLU import * 
from OpenGL.GLUT import * 
from PIL import Image 
import time, sys 
import numpy as np 


WIDTH = 400 
HEIGHT = 300 

def InitGL(): 
    glMatrixMode(GL_PROJECTION) 
    gluPerspective(45.0, float(WIDTH)/float(HEIGHT), 0.1, 100.0) 
    glMatrixMode(GL_MODELVIEW) 


def DrawGLScene(): 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 
    glLoadIdentity() 
    glTranslatef(0, 0., -3) 
    glutWireTeapot(1) 
    glFlush() 

def capture_screen(): 
    DrawGLScene() 
    glPixelStorei(GL_PACK_ALIGNMENT, 1) 
    data = glReadPixels(0, 0, WIDTH, HEIGHT, GL_RGBA, GL_UNSIGNED_BYTE) 
    image = Image.fromstring("RGBA", (WIDTH, HEIGHT), data) 
    image.transpose(Image.FLIP_TOP_BOTTOM).show() 

def capture_fbo(width=800, height=600): 

    fbo = glGenFramebuffers(1) 
    render_buf = glGenRenderbuffers(1) 

    glBindRenderbuffer(GL_RENDERBUFFER, render_buf) 

    glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA, width, height); 
    glBindFramebuffer(GL_FRAMEBUFFER, fbo) 
    glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, render_buf); 
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo); 

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) 
    glMatrixMode(GL_MODELVIEW) 
    glLoadIdentity() 
    glTranslatef(1, 1., -3) 
    glScale(width/WIDTH, height/HEIGHT, 1) 
    glutWireTeapot(1.0) 
    glFlush() 
    glReadBuffer(GL_COLOR_ATTACHMENT0); 
    data = glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE) 
    glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); 
    image = Image.fromstring("RGBA", (width, height), data) 
    image.transpose(Image.FLIP_TOP_BOTTOM).show() 

    glDeleteFramebuffers(1, [fbo]); 
    glDeleteRenderbuffers(1, [render_buf]); 


glutInit(sys.argv) 
glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH) 
glutInitWindowSize(WIDTH, HEIGHT) 
window = glutCreateWindow("") 
glutDisplayFunc(DrawGLScene) 
InitGL() 
DrawGLScene() 
capture_screen() 
capture_fbo() 

glutMainLoop() 

,但沒有在該地區被描繪的常態屏幕窗口區域外 enter image description here

+0

創建一個更高分辨率的FBO渲染到它並保存 –

+0

我已經嘗試過,但我沒有成功看到有問題的編輯 –

回答

0

方式glReadPixels的工作原理是它從當前選擇的幀緩衝區中讀取像素。

不確定幀緩衝是什麼?這裏是維基頁面:http://www.opengl.org/wiki/Framebuffer_Object

一個簡單的解釋是,您可以將幀緩衝區視爲您的圖形卡所用的「畫布」。您可以擁有任意數量的幀緩衝區(sorta ...大多數驅動程序在某處定義了一個限制),但只會顯示一個限制。這是所選的幀緩衝區,並且只能與您在屏幕上顯示的窗口一樣大。

這裏有上作出的framebuffer教程:http://www.lighthouse3d.com/tutorials/opengl-short-tutorials/opengl_framebuffer_objects/

修改它,這樣你所創建的幀緩衝區是要採取從截圖的分辨率。

一旦幀緩衝區設置,您可以繪製它像這樣:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, buffer); 
/* drawing code */ 
glReadPixels(); 

如果你希望能夠仍然在屏幕上看到的東西,你將需要畫到默認的幀緩衝繪製到新的幀緩衝區後:

glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); //"0" means return to default framebuffer 
/* same drawing code */ 

請注意,這意味着您將繪製整個場景兩次!確保你的幀率可以處理它。