我的程序有两个不同的QGLWidget时访问冲突

时间:2014-11-12 08:32:13

标签: c++ qt opengl qglwidget

我有两个不同的QGLWidgets(GLViwer和TextureViwer),我将它们添加到两个QHboxLayout

glviewer = GLViewer::getInstance(); //QGLWidget singleton, display 3d model
texViewer = TextureViewer::getInstance();//display selected texture
ui.modelViewer->addWidget(glviewer); //add it to QHboxLayout
ui.textureViewer->addWidget(texViewer);

我使用glDrawArrays()渲染模型,因为它很快。当我只有GLViewer来显示3d模型时,我没有问题。但是当我有两个QGLWidget时。这会引起问题。

  

访问冲突读取位置0x00000000 ...

我尝试逐步渲染模型(绘制一个三角形和另一个......),即使我调用glTexCoord2f(),它也可以工作但没有纹理。

我不知道为什么会这样。请帮帮我:)。

以下是我的初始数据代码

glGenBuffers(3, this->buffers);

glBindBuffer(GL_ARRAY_BUFFER, this->buffers[VERTEXBUFFER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9*objInfo->faces.size(), this->vertexs, GL_STATIC_DRAW);
glVertexPointer(3, GL_FLOAT, 0, BUFFER_OFFSET(0));

glBindBuffer(GL_ARRAY_BUFFER, this->buffers[NORMALBUFFER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*9*objInfo->faces.size(), this->normals, GL_STATIC_DRAW);
glNormalPointer(GL_FLOAT, 0, BUFFER_OFFSET(0));

glBindBuffer(GL_ARRAY_BUFFER, this->buffers[TEXCOORDBUFFER]);
glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat)*6*objInfo->faces.size(), this->texCoord, GL_STATIC_DRAW);
glTexCoordPointer(2, GL_FLOAT, 0, BUFFER_OFFSET(0));

BUFFER_OFFSET(0)就像红皮书一样

#define BUFFER_OFFSET(bytes) ((GLubytes*) NULL+(bytes))

GLViewer.h

class GLViewer : public QGLWidget
{
    Q_OBJECT
public:
    ~GLViewer();
    GLViewer(QWidget *parent = 0);
    void drawModelWithTexArrayBuffer();
protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int w, int h);
};

GLViewer.cpp

void GLViewer::initializeGL()
{
glewInit();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
glEnable(GL_CULL_FACE); 
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK); 
glFrontFace(GL_CCW);
glShadeModel(GL_SMOOTH);
}

void GLViewer::paintGL()
{

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

if (isLoaded)
{
    timeCount.start();
    glLoadIdentity();

    glTranslated(modelCenter[0]+offsetX-(maxX+minX)/2,modelCenter[1]+ offsetY-(maxY+minY)/2 ,modelCenter[2]+zoomRate+minZ-3*(maxZ - minZ));
    glMultMatrixf(this->arcBall->Transform.M);
    glTranslated(-modelCenter[0], -modelCenter[1], -modelCenter[2]);
    if (this->modelWithtTex)
    {
        setLight(this->lightOn);
        if (showMesh)
        {
            drawModelLineArrayBuffer();
        }
        else
        {
            drawModelWithTexArrayBuffer();
            //drawModelWithTex();
        }
    }
    else
    {
        drawModelWithoutTexArrayBuffer();
    }
    int elapseTime = timeCount.elapsed();
}
} 

void GLViewer::resizeGL( int w, int h )
{
if (h == 0)
{
    h = 1;
}

    this->curWidth = w;
    this->curHeight = h;
    glViewport(0, 0, (GLsizei) w, (GLsizei) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();

    gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1, 2000.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    this->arcBall->setBounds((GLfloat)w, (GLfloat)h);
}
void GLViewer::drawModelWithTexArrayBuffer()
{
    glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
    glEnable(GL_TEXTURE_2D);
    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
    glEnableClientState(GL_VERTEX_ARRAY);
    glEnableClientState(GL_NORMAL_ARRAY);
    glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    for (int i = 0 ; i < objInfo->tex_filenames.size(); i++)
    {
        if (indRange[i].length == 0)
            continue;
        else
        {
            glBindTexture(GL_TEXTURE_2D, texName[indRange[i].texId]);
            glDrawArrays(GL_TRIANGLES, indRange[i].start, indRange[i].length);
        }
    }
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
}   

TextureViewer.h

class TextureViewer : public QGLWidget
{
Q_OBJECT

public:

~TextureViewer();
TextureViewer(QWidget *parent = 0);
protected:
    void initializeGL();
    void paintGL();
    void resizeGL(int w, int h);
};

TextureViewer.cpp

void TextureViewer::initializeGL()
{
std::cout << "ddd" << std::endl;
glewInit();
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
glEnable(GL_CULL_FACE); 
glEnable(GL_DEPTH_TEST);
glCullFace(GL_BACK); 
glFrontFace(GL_CCW);
glShadeModel(GL_SMOOTH);
}

void TextureViewer::paintGL()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();
glTranslated(0, 0, -1);
glColor4f(1, 0, 1, 1);
glRectd(0,0,1,1);
}

void TextureViewer::resizeGL( int w, int h )
{
if (h == 0)
{
    h = 1;
}
glViewport(0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();

gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1, 2000.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

}

1 个答案:

答案 0 :(得分:0)

每个QGLWidget都有自己的OpenGL上下文,因此状态,即使您将它们创建为共享上下文,此共享也不包括顶点数组指针位置等内容。因此,您必须在致电gl…PointerglDrawElements之前拨打正确的glDrawArrays来电。你不能正确地做到这一点。