1

5メガピクセルのテクスチャがあり、更新に問題があります。テクスチャは、ビデオストリームと同じように長方形に表示されます。

OpenGLコマンドはすばやく実行されますが、実際のテクスチャ更新レートは最適ではなく、おそらく1秒あたり3フレームしかありません。多少の変更はありますが、小さいテクスチャ(500x500)を使用した場合はあまり変更されません。

マシンにはNVIDIAgtx570が搭載されています

私の最初の努力はとを使用することでしたglTexSubImage2DglBufferSubData、これらはメモリマップドスキームよりもわずかに劣っていました。

グラフィックカードにテクスチャを更新させる方法はありますか?ビデオストリーミングソフトウェアはどのように作成されていますか?

レンダリングループ

void glStream::paintGL()
{
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glLoadIdentity();
    program1.bind();
    program1.setUniformValue("texture", 0);
    program1.enableAttributeArray(vertexAttr1);
    program1.enableAttributeArray(vertexTexr1);
    program1.setAttributeArray(vertexAttr1, vertices.constData());
    program1.setAttributeArray(vertexTexr1, texCoords.constData());
    //
    glECheck();
    glBindTexture(GL_TEXTURE_2D, textures[0]);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,pbos[0]);
    void* memory = glMapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,GL_WRITE_ONLY);
    device->fillBuffer((unsigned char *)memory,heightGL,widthGL); // takes 2ms (not long)
    glUnmapBuffer(GL_PIXEL_UNPACK_BUFFER_ARB);
    glTexSubImage2D(GL_TEXTURE_2D,0,0,0,widthGL,heightGL,GL_LUMINANCE,GL_UNSIGNED_BYTE, NULL);
    glDrawArrays(GL_TRIANGLES, 0, vertices.size());
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB,0);
    glBindTexture(GL_TEXTURE_2D,0);
    //
    program1.disableAttributeArray(vertexTexr1);
    program1.disableAttributeArray(vertexAttr1);
    program1.release();
    glECheck();//no errors
}

テクスチャ予約

void glStream::reserveTextures()
{
    assert(numGLFrames>0);
    assert(glGenBuffers);
    displayBuff = (GLubyte*) calloc(numGLFrames*widthGL*heightGL,sizeof(GLubyte));//GL_RGB8
    memset(displayBuff,100,numGLFrames*widthGL*heightGL*sizeof(GLubyte));
    glGenBuffers(1,&pbos[0]);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, pbos[0]);
    glBufferData(GL_PIXEL_UNPACK_BUFFER_ARB,
                 numGLFrames*widthGL*heightGL*sizeof(GLubyte),
                 &displayBuff[0], GL_STREAM_DRAW);
    glBindBuffer(GL_PIXEL_UNPACK_BUFFER_ARB, 0);
    glGenTextures(1,&textures[0]);
    glBindTexture(GL_TEXTURE_2D,textures[0]);
    glTexImage2D(GL_TEXTURE_2D,0,GL_LUMINANCE,
                 widthGL,heightGL,0,GL_LUMINANCE,GL_UNSIGNED_BYTE,NULL);
    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_GENERATE_MIPMAP, GL_FALSE);
    glBindTexture(GL_TEXTURE_2D,0);
}

初期化

void glStream::initializeGL()
{
    GLenum err = glewInit();
    if (GLEW_OK != err)
    {
        const char * emssage = (const char*)glewGetErrorString(err);
        QMessageBox::information(0, "OpenGL 3.x Context Example",
                                 emssage);
        exit(20);
    }
    glDisable(GL_DEPTH_TEST);
    QGLShader *vshader1 = new QGLShader(QGLShader::Vertex, this);
    const char *vsrc1 =
        "attribute vec2 coord2d;   \n"
        "attribute mediump vec4 texCoord;\n"
        "varying mediump vec4 texc;\n"
        "void main()                  \n"
        "{                            \n"
        "   gl_Position = vec4(coord2d, 0.0, 1.0); \n"
        "   texc = texCoord;\n"
        "}                          \n";
    vshader1->compileSourceCode(vsrc1);
    QGLShader *fshader1 = new QGLShader(QGLShader::Fragment, this);
    const char *fsrc1 =
        "uniform sampler2D texture;\n"
        "varying mediump vec4 texc;\n"
        "void main(void)\n"
        "{\n"
        "    gl_FragColor = texture2D(texture, texc.st);\n"
        "}\n";
    fshader1->compileSourceCode(fsrc1);
    program1.addShader(vshader1);
    program1.addShader(fshader1);
    program1.link();
    vertexAttr1 = program1.attributeLocation( "coord2d");
    vertexTexr1 = program1.attributeLocation( "texCoord");
    // Create the vertex buffer.
    vertices.clear();
    float u=1;
#define AVEC -u,u
#define BVEC -u,-u
#define CVEC u,u
#define DVEC u,-u
    vertices << QVector2D(AVEC);vertices << QVector2D(BVEC);
    vertices << QVector2D(CVEC);vertices << QVector2D(BVEC);
    vertices << QVector2D(DVEC);vertices << QVector2D(CVEC);
    // Create the texture vertex buffer
#define TAVEC 0,1
#define TBVEC 0,0
#define TCVEC 1,1
#define TDVEC 1,0
    texCoords << QVector2D(TAVEC);texCoords << QVector2D(TBVEC);
    texCoords << QVector2D(TCVEC);texCoords << QVector2D(TBVEC);
    texCoords << QVector2D(TDVEC);texCoords << QVector2D(TCVEC);
    glECheck();
    reserveTextures();
}

編集1

コードの他の部分でこのテクスチャをファイルに書き込んでいるので、フィルバッファが新しいテクスチャを思い付くと確信していますが、実際には異なります。私のファイルIOがOpenGLテクスチャよりも速いのは悲しい日です。

編集 2FRAPSを試し、レンダリングループが約18 FPSで実行されていることを確認しましたが、表示される更新は遅くなります(おそらく3 FPS)。そのような不一致の原因は何でしょうか?

4

1 に答える 1

1

glBufferDataの呼び出しでは、PBOはテクスチャよりもはるかに大きくなります。

numGLFrames*widthGL*heightGL*sizeof(GLubyte)

複数のテクスチャ(フレーム)に十分な大きさのPBOを割り当てていますが、1フレーム分のデータの読み取り/書き込みのみを行っています。

PBOをテクスチャと同じサイズにし、glTexSubImage2Dの代わりにglTexImage2Dを使用する場合、それははるかに高速ですか?

于 2013-02-25T17:53:35.253 に答える