Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt OpenGL纹理速度太慢?_Qt_Opengl_Pixel_Texture Mapping_Pixel Manipulation - Fatal编程技术网

Qt OpenGL纹理速度太慢?

Qt OpenGL纹理速度太慢?,qt,opengl,pixel,texture-mapping,pixel-manipulation,Qt,Opengl,Pixel,Texture Mapping,Pixel Manipulation,我有一个500万像素的纹理,我更新有困难。纹理显示在与视频流不同的矩形上 OpenGL命令执行速度很快,但实际纹理更新速率次优,可能每秒仅3帧。使用较小的纹理(500x500)时会有一些变化,但变化不大 该机器具有NVIDIA gtx 570 我最初的努力是使用glTexSubImage2D和glBufferSubData,但它们的性能比内存映射方案稍差 有没有办法强制图形卡更新纹理?视频流软件是如何编写的 渲染循环 void glStream::paintGL() { glClear(

我有一个500万像素的纹理,我更新有困难。纹理显示在与视频流不同的矩形上

OpenGL命令执行速度很快,但实际纹理更新速率次优,可能每秒仅3帧。使用较小的纹理(500x500)时会有一些变化,但变化不大

该机器具有NVIDIA gtx 570

我最初的努力是使用
glTexSubImage2D
glBufferSubData
,但它们的性能比内存映射方案稍差

有没有办法强制图形卡更新纹理?视频流软件是如何编写的

渲染循环

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();
}
初始化

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();
}
void glStream::initializeGL()
{
GLenum err=glewInit();
如果(GLEW_OK!=错误)
{
常量字符*emessage=(常量字符*)glewGetErrorString(错误);
信息(0,“OpenGL 3.x上下文示例”,
信息);
出口(20);
}
glDisable(GLU深度测试);
QGLShader*vshader1=新的QGLShader(QGLShader::Vertex,this);
常量字符*vsrc1=
“属性vec2 coord2d;\n”
“属性mediump vec4 texCoord;\n”
“可变介质矢量4 texc;\n”
“void main()\n”
“{\n”
“gl_Position=vec4(coord2d,0.0,1.0);\n”
“texc=texCoord;\n”
“}\n”;
vshader1->编译源代码(vsrc1);
QGLShader*fshader1=新的QGLShader(QGLShader::Fragment,this);
常量字符*fsrc1=
“二维纹理的均匀采样;\n”
“可变介质矢量4 texc;\n”
“作废主(作废)\n”
“{\n”
gl_FragColor=texture2D(纹理,texc.st);\n
“}\n”;
fshader1->编译资源代码(fsrc1);
program1.addShader(vshader1);
program1.addShader(fshader1);
程序1.link();
vertexAttr1=程序1.属性位置(“coord2d”);
vertexTexr1=program1.attributeLocation(“texCoord”);
//创建顶点缓冲区。
顶点。清除();
浮点数u=1;
#定义AVEC-u,u
#定义BVEC-u,-u
#定义CVEC u,u
#定义DVEC u,-u

顶点在调用glBufferData时,PBO比纹理大得多:

numGLFrames*widthGL*heightGL*sizeof(GLubyte)
您正在为多个纹理(帧)分配足够大的PBO,但只能读取/写入一帧的数据


如果将PBO设置为与纹理相同的大小,并使用glTexImage2D而不是glTexSubImage2D,速度是否会更快?

在调用glBufferData时,PBO比纹理大得多:

numGLFrames*widthGL*heightGL*sizeof(GLubyte)
您正在为多个纹理(帧)分配足够大的PBO,但只能读取/写入一帧的数据


如果将PBO设置为与纹理相同的大小,并使用glTexImage2D而不是glTexSubImage2D,速度会快得多吗?

我自己不是这方面的专家,但既然您提到您有一个Nvidia卡,并且希望图形卡能够直接更新OpenGL缓冲区,那么您考虑过使用Cuda吗?有很多问题需要解决Nvidia开发者页面上的r个例子项目正好说明了这一点。你选择的词语<代码>真实纹理更新率让我想知道这句话到底是什么意思?你测量了吗?是什么代码导致你的重绘发生?它们发生的频率有多高?在下面的评论中,你说了大约20fps的话:你在说我吗ng
paintGL()
每秒被调用大约20次,但每秒仅调用3次您会在屏幕上看到更新的纹理?如果是:您确定
fillBuffer()
每次调用时都会出现一个“新”纹理?@axxel是的,这正是我的意思,我相信fill buffer会出现一个新纹理,因为在代码的其他部分,我将这个纹理写入文件,它确实不同。当你的文件IO比OpenGL纹理快时,这是一个悲伤的日子。这听起来很奇怪。我不这么认为你可以试试
glDrawArrays(GL_三角形,0,顶点.size()/(++i%2)+1))之类的东西吗
并检查您的quad是否有一半以20fps的速度闪烁?我认为axxel是对的,似乎每次调用device->fillBuffer时都没有创建“新”纹理。我自己也不是这方面的专家,但既然您提到您有一个Nvidia卡,并且希望图形卡能够直接更新您的OpenGL缓冲区,那么:您有吗考虑过使用Cuda吗?Nvidia的开发者页面上有相当多的示例项目正好说明了这一点。你选择的词语
真实纹理更新率
让我想知道这句话到底意味着什么?你测量了吗?是什么代码导致你的重绘发生?它们发生的频率有多高?在评论中下面你说了一些关于20fps的事情:你是说
paintGL()
每秒被调用20次,但每秒只有3次,你会在屏幕上看到更新的纹理吗?如果是:你确定
fillBuffer()
每次调用时都会出现一个“新”纹理?@axxel是的,这正是我的意思,我相信fill buffer会出现一个新纹理,因为在代码的其他部分,我将这个纹理写入文件,它确实不同。当你的文件IO比OpenGL纹理快时,这是一个悲伤的日子。这听起来很奇怪。我不这么认为你可以试试
glDrawArrays(GL_三角形,0,顶点.size()/(++i%2)+1))之类的东西吗;
并检查您的四元网格是否有一半以20fps的速度闪烁?我认为axxel是对的,似乎每次调用device->fillBuffer时都不会创建“新”纹理。感谢您的建议,虽然它不是很实时,但速度会快一点。有什么想法吗?您的内存中是否已经准备好绘制所有帧,或者您是否正在使用capturi