OpenGL正在泄漏内存.哪个对象没有被释放? [英] OpenGL is leaking memory. Which object is not being released?

查看:457
本文介绍了OpenGL正在泄漏内存.哪个对象没有被释放?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的OpenGL渲染有问题. RAM内存荒谬地增长到整个系统死机的程度.我已经确定,如果我评论整个渲染功能,则根本不会增加内存.因此,问题在于我的OpenGL渲染函数可能正在为某些东西分配内存,而我没有释放它.

I'm having problems with my OpenGL rendering. The RAM memory grows absurdly up to the point the entire system freezes. I've identified that if I comment the entire render function, no memory grows at all. Therefore the problem is that my OpenGL render function might be allocating memory for something and I'm not releasing it.

您能找出问题所在吗?

Can you identify what is the problem?

PS:if内部的东西实际上只运行一次,因此它的内存分配只发生一次

PS: the thing inside the if actually runs one single time, so the allocation of memory it does, occur only one time

这是我的OpenGL渲染功能:

This is my OpenGL render function:

void OpenGlVideoQtQuickRenderer::render()
{
    if (this->firstRun) {
        std::cout << "Creating QOpenGLShaderProgram " << std::endl;
        this->firstRun = false;
        program = new QOpenGLShaderProgram();
        initializeOpenGLFunctions();
        //this->m_F  = QOpenGLContext::currentContext()->functions();

        datas[0] = new unsigned char[width*height];     //Y
        datas[1] = new unsigned char[width*height/4];   //U
        datas[2] = new unsigned char[width*height/4];   //V

        std::cout << program->addShaderFromSourceCode(QOpenGLShader::Fragment, tString2) << std::endl;
        std::cout << program->addShaderFromSourceCode(QOpenGLShader::Vertex, vString2) << std::endl;

        program->bindAttributeLocation("vertexIn",A_VER);
        program->bindAttributeLocation("textureIn",T_VER);
        std::cout << "program->link() = " << program->link() << std::endl;

    }
    program->bind();


    glVertexAttribPointer(A_VER, 2, GL_FLOAT, 0, 0, ver);
    glEnableVertexAttribArray(A_VER);

    glVertexAttribPointer(T_VER, 2, GL_FLOAT, 0, 0, tex);
    glEnableVertexAttribArray(T_VER);

    unis[0] = program->uniformLocation("tex_y");
    unis[1] = program->uniformLocation("tex_u");
    unis[2] = program->uniformLocation("tex_v");

    glGenTextures(3, texs);

    //Y
    glBindTexture(GL_TEXTURE_2D, texs[0]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

    //U
    glBindTexture(GL_TEXTURE_2D, texs[1]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width/2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

    //V
    glBindTexture(GL_TEXTURE_2D, texs[2]);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, width / 2, height / 2, 0, GL_RED, GL_UNSIGNED_BYTE, 0);

    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texs[0]);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RED, GL_UNSIGNED_BYTE, datas[0]);
    glUniform1i(unis[0], 0);


    glActiveTexture(GL_TEXTURE0+1);
    glBindTexture(GL_TEXTURE_2D, texs[1]); 
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width/2, height / 2, GL_RED, GL_UNSIGNED_BYTE, datas[1]);
    glUniform1i(unis[1],1);


    glActiveTexture(GL_TEXTURE0+2);
    glBindTexture(GL_TEXTURE_2D, texs[2]);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width / 2, height / 2, GL_RED, GL_UNSIGNED_BYTE, datas[2]);
    glUniform1i(unis[2], 2);

    glDrawArrays(GL_TRIANGLE_STRIP,0,4);
    program->disableAttributeArray(A_VER);
    program->disableAttributeArray(T_VER);
    program->release();
}

推荐答案

该代码正在每个帧(glGenTextures)中创建三个新纹理,而从未释放它们(glDeleteTextures).您可以在render方法的末尾删除它们,或者甚至更好:在第一个块中仅创建一次纹理,然后仅将新数据上传到它们.

The code is creating three new textures in each frame (glGenTextures) without ever releasing them (glDeleteTextures). Either you delete them at the end of the render method, or even better: You only create the textures once in the first block and then only upload new data to them.

仅用于记录:通过在glVertexAttribPointer中指定地址从CPU内存中提取仅在OpenGL核心配置文件之前有效.我强烈建议改用顶点缓冲区对象".

Just for the records: Drawing from CPU memory by specifying the address in glVertexAttribPointer is only valid in OpenGL before Core profile. I highly suggest to use Vertex Buffer Objects instead.

这篇关于OpenGL正在泄漏内存.哪个对象没有被释放?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆