2016-04-14 268 views
0

我想呈现一个简单的二维图像与QOpenGLWidget使用四作为纹理。但无论我在尝试什么,我总是会得到一个黑盒子。QOpenGLWidget纹理映射结果黑屏

我看过很多教程,我有一个简单pixelbuffer这样

uchar* m_pData; 

存储我的RGB值。这是有效的,因为我已经用glDrawPixles()进行了测试。考虑到OpenGLWidget,我将发布三个最重要的功能。

initializeGL()第一名:

void QGLImageviewer::initializeGL() 
{ 
initializeOpenGLFunctions(); 

// Clear the color 
float r = ((float)m_backColor.darker().red())/255.0f; 
float g = ((float)m_backColor.darker().green())/255.0f; 
float b = ((float)m_backColor.darker().blue())/255.0f; 
glClearColor(r,g,b,1.0f); 

// Set shading model. 
glShadeModel(GL_SMOOTH); 

// Set the viewport 
glViewport(0.f, 0.f, m_origW, m_origH); 

// Init. Projection Matrix 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
glOrtho(0.0, m_origW, m_origH,0.0,1.0,-1.0); 

// Init Modelview Matrix 
glClearColor(0.f, 0.f, 0.f, 1.f); 

// Enable texturing 
glEnable(GL_TEXTURE_2D); 


// Generate texture ID 
glGenTextures(1, &m_textureID); 

// Bind texture ID 
glBindTexture(GL_TEXTURE_2D, m_textureID); 

// Set texture parameters 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 
//glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

// Generate Texture, and assign pixles to our texture ID 
if (m_pData != nullptr) 
{ 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW, m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*)m_pData); 
} 
else 
{ 
    qCritical("Buffer is empty!!"); 
} 

// Unbind texture 
glBindTexture(GL_TEXTURE_2D, NULL); 

// Check for Error 
GLenum error_ = glGetError(); 
if (error_ != GL_NO_ERROR) 
{ 
    qCritical("Error Loading Texture!"); 
} 

} 

然后paintGL():

void QGLImageviewer::paintGL() 
{ 
makeCurrent(); 

glClearColor(0.0f, 0.0f, 0.0f, 0.0f); 
// Clear Screen And Depth Buffer 
glClear(GL_COLOR_BUFFER_BIT); 

if (!(m_renderQtImg->isNull())) 
{ 
    //QImage image; 

    int imWidth = m_renderQtImg->width(); 
    int imHeight = m_renderQtImg->height(); 

    // The image has to be resized to fit the widget 
    if (imWidth != this->size().width() && 
     imHeight != this->size().height()) 
    { 

     imWidth = this->size().width(); 
     imHeight = this->size().height(); 
    } 
    else 
    { 
     //image = *m_renderQtImg; 

     imWidth = m_origW; 
     imHeight = m_origH; 
    } 

    if (m_textureID != 0) 
    { 
     glMatrixMode(GL_MODELVIEW); 
     // Remove any previous transformations 
     glLoadIdentity(); 

     glPushMatrix(); 

     // Move to rendering point 
     glTranslatef(0.f, 0.f, 0.f); 
     glColor3f(0.0f, 0.0f, 0.5f); 

     // Set texture ID 
     glBindTexture(GL_TEXTURE_2D, m_textureID); 

     glBegin(GL_QUADS); 
     glTexCoord2f(0.f, 0.f); glVertex2f(0.f, 0.f); 
     glTexCoord2f(1.f, 0.f); glVertex2f(imWidth, 0.f); 
     glTexCoord2f(1.f, 1.f); glVertex2f(imWidth, imHeight); 
     glTexCoord2f(0.f, 1.f); glVertex2f(0.f, imHeight); 
     glEnd(); 

     //glDisable(GL_TEXTURE_2D); 
     glPopMatrix(); 
     glFlush(); 

    } 
} 
} 

最后但并非最不重要的resizeGL():

void QGLImageviewer::resizeGL(int width, int height) 
{ 
makeCurrent(); 
glViewport(0,0,(GLint)width,(GLint)height); 
glMatrixMode(GL_PROJECTION); 
glLoadIdentity(); 
//gluOrtho2D(0.0, width, 0.0, height); 
glOrtho(0.0, width, 0.0, height, 0.0, 1.0); 

} 

我使用Qt5.6和Microsoft Visual Studio 2015编译器。

回答

0

妈的,这个问题是在

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW , m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (float*)m_pData); 

我的成员变量m_orgiWm_orgiH被初始化为0。所以我的代码无法工作,这一点并不令人惊讶。

为了记录,我将发布我的运行代码,QOpenGLWidget的三个最重要的功能,希望对有同样问题的人有用。

void QGLImageviewer::initializeGL() 
{ 
initializeOpenGLFunctions(); 

float r = ((float)m_backColor.darker().red())/255.0f; 
float g = ((float)m_backColor.darker().green())/255.0f; 
float b = ((float)m_backColor.darker().blue())/255.0f; 
glClearColor(r,g,b,1.0f); 

// Generate texture ID 
glGenTextures(1, &m_textureID); 

// Bind texture ID 
glBindTexture(GL_TEXTURE_2D, m_textureID); 

if (m_pData != nullptr) 
{ 
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, m_origW , m_origH, 0, GL_RGB, GL_UNSIGNED_BYTE, (float*)m_pData); 
} 
else 
{ 
    qCritical("Buffer is empty!!"); 
} 

// Set texture parameters 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); //IMPORTANT FOR NON POWER OF 2 TEXTURES 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 

// Enable texturing Mapping 
glEnable(GL_TEXTURE_2D); 

// Enable Smooth Shading 
glShadeModel(GL_SMOOTH); 

// Black Background 
glClearColor(0.0f, 0.0f, 0.0f, 0.5f); 

// Depth Buffer Setup 
glClearDepth(1.0f); 

// Enables Depth Testing 
glEnable(GL_DEPTH_TEST); 

// Type of depth testing to do 
glDepthFunc(GL_LEQUAL); 

// Really Nice Perspective Calculations 
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); 

// Unbind Texture 
glBindTexture(GL_TEXTURE_2D, NULL); 
} 

现在paintGL()

void QGLImageviewer::paintGL() 
{ 
makeCurrent(); 

// Clear Screen And Depth Buffer 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

glEnable(GL_TEXTURE_2D); 
glBindTexture(GL_TEXTURE_2D, m_textureID); 

glBegin(GL_QUADS); 
// Drawing the quad with the texture mapped on it 
// 
// OpenGL 2D Coordinates 
// Sticking with the Coordinate Convention mentioned here 
glTexCoord2f(1.0f, 0.0f); glVertex2f(m_width, 0.0f); // vertex 1 
glTexCoord2f(1.0f, 1.0f); glVertex2f(m_width, m_height); // vertex 2 
glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, m_height); // vertex 3 
glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); // vertex 4 

glEnd(); 


} 

而且resizeGL()

void QGLImageviewer::resizeGL(int width, int height) 
{ 
makeCurrent(); 

m_width = width; 
m_height = height; 

// Compute aspect ratio of the new window 
if (height == 0) height = 1;    // To prevent divide by 0 
GLfloat aspect = (GLfloat)width/(GLfloat)height; 

// Set the viewport to cover the new window 
glViewport(0, 0, width, height); 

// Set the aspect ratio of the clipping area to match the viewport 
glMatrixMode(GL_PROJECTION); // To operate on the Projection matrix 
glLoadIdentity();    // Reset the projection matrix 

glOrtho(0, m_width/ m_zoomFactor, m_height/ m_zoomFactor,0, -1, 1); 

}