2015-03-13 92 views
0

我一直在嘗試使用OpenGL將圖像渲染到屏幕上,並且爲了瞭解有關紋理等的更多信息,我的方法是將圖像映射到紋理,然後使用GL_QUADS繪製圖像。但是,我得到的只是一個空白的屏幕。無法顯示OpenGL紋理

所以,紋理被初始化爲如下:

class Texture 
{ 
public: 
    void init_texture(int rows, int cols); 
    void load_texture(const Image * frame); 

    GLuint  _texture_obj; 

}; 

void Texture::init_texture(int rows, int cols) 
{ 
    if (_texture_obj) glDeleteTextures(1, &_texture_obj); 

    _texture_target = GL_TEXTURE_2D; 
    glGenTextures(1, &_texture_obj); 

    if (_texture_obj) { 
     glBindTexture(_texture_target, _texture_obj); 
     glTexImage2D(_texture_target, 0, GL_BGRA, cols, rows, 0, 
        GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)NULL); 
     glTexParameterf(_texture_target, GL_TEXTURE_MIN_FILTER, 
         GL_LINEAR); 
     glTexParameterf(_texture_target, GL_TEXTURE_MAG_FILTER, 
         GL_LINEAR); 
    } 
    else { 
     throw std::runtime_error("Could not create the OpenGL texture"); 
    } 
} 

void Texture::load_texture(const Image *frame) 
{ 
    glBindTexture(GL_TEXTURE_2D, _texture_obj); 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, frame->cols(), 
        frame->rows(), GL_BGRA, GL_UNSIGNED_BYTE, 
        frame->data()); 
} 

上述代碼初始化並加載紋理。

要顯示的質感,我用一個QOpenGLWidget派生對象在初始化和paint方法是這樣的:

class GLWidget: public QOpenGLWidget 
{ 
public: 
    GLWidget(Image *image); 
    void initializeGL(); 
    void resizeGL(int w, int h); 
    void paintGL(); 

private: 
    Texture texture; 
}; 


void GLWidget::GLWidget(Image * image) 
{ 
    texture.init(image->rows, image->cols); 
    texture.load(image); 
} 

void GLWidget::initializeGL() 
{ 
    glEnable(GL_DEPTH_TEST); 
    glEnable(GL_CULL_FACE); 
} 

void GLWidget::resizeGL(int w, int h) 
{} 

void GLWidget::paintGL() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glLoadIdentity();  
    glEnable(GL_TEXTURE_2D); 
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,GL_REPLACE); 
    glBindTexture(GL_TEXTURE_2D, texture._tex_object); 
    glBegin(GL_QUADS); 
     // width(), height() gives the component width and height 
     glTexCoord2i(0, 0); glVertex2i(0, 0); 
     glTexCoord2i(0, 1); glVertex2i(0, this->width()); 
     glTexCoord2i(1, 1); glVertex2i(this->height(), this->width()); 
     glTexCoord2i(1, 0); glVertex2i(this->height(), 0); 
    glEnd(); 
    glDisable(GL_TEXTURE_2D); 
} 

然而,這隻能說明我一個空白屏幕。是否有一些我需要設置的視口?我幾天前纔開始使用OpenGL,所以在這方面非常綠色。我在Linux上使用qt版本5.4和OpenGL 4.3。

+0

'tex_id'是否是'GLWidget'的成員?它是如何填充的?發佈[MCVE](http://stackoverflow.com/help/mcve)。 – genpfault 2015-03-13 18:12:41

+0

添加它使其更清晰。希望沒關係。 – Luca 2015-03-13 18:34:51

回答

3

呼叫

glTexImage2D(_texture_target, 0, GL_BGRA, cols, rows, 0, GL_BGRA, GL_UNSIGNED_BYTE, (GLvoid *)NULL); 

是無效的,因爲GL_BGRA不是有效internalFormat。你應該使用GL_RGBA。請注意,internalFormat只是定義了基本數據類型和通道數量,實際佈局完全是特定於實現的。另一方面,format參數告訴GL如何解釋客戶端內存中的數據,因此實際定義了GL_RGBAGL_BGRA等格式。我不太熟悉QOpenGLWidget。不過,我認爲在構造函數中創建紋理可能不是一個好主意,因爲GL上下文在此時可能不可用(或者至少不會對該線程產生當前效果)。你應該把這些東西放入initializeGL()

+0

它不是實際在構造函數中創建的。代碼的實際佈局稍微複雜一點,我簡化了它。但是,我證實了OPenGLContext是有效的(由於父類是QOpenGLWidget而被調用),但是我必須等到週末結束以驗證這種錯誤的內部格式是否確實是原因,因爲我不知道如何使用ssh到我的工作計算機,並使OpenGL正常工作,並且我的主機沒有安裝。我會在星期一做一些測試後立即更新這個線程 – Luca 2015-03-13 21:11:04

+0

所以,我做了這個改變,但它仍然沒有渲染紋理 – Luca 2015-03-17 10:18:57

+0

你完全不清楚你的轉換是如何設置的,所以沒有人可以知道屏幕上應該出現的位置(如果有的話) – derhass 2015-03-17 19:51:48