当在循环中调用glCreateProgram(),如果没有调用glDeleteProgram()方法释放内存就会导致内存泄漏,但我觉得这样一对一调用并不方便拓展功能,我再MyShaderClass类中确保只有一个program变量并每次调用它时检查是否存在,如果存在就用这个,不存在则从创建一个,当调用glLinkProgram()把着色器程序链接完成后就调用glDetachShader()方法解除program变量的着色器联系,这样下次就不必创建一个新的变量而是继续用这个变量重新联系着色器代码编译即可,由于只创建一次也就不存在内存泄漏了。

具体代码段如下

    class MyShaderClass
    {
    public:
        GLuint Program;
        void MyShaderPath(std::string vertexPath, std::string fragmentPath);
        void MyShader(std::string vertexShaderSource, std::string fragmentShaderSource);
        GLuint MyUse();
        ~MyShaderClass();
    };
    void MyShaderClass::MyShader(std::string vertexShaderSource, std::string fragmentShaderSource) {

        GLuint vertex, fragment;
        GLint success;
        GLchar infoLog[512];
        const GLchar* vertexSource = vertexShaderSource.c_str();
        const GLchar* fragmentSource = fragmentShaderSource.c_str();
        // 顶点着色器
        vertex = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertex, 1, &vertexSource, NULL);
        glCompileShader(vertex);
        // 打印编译错误(如果有的话)
        glGetShaderiv(vertex, GL_COMPILE_STATUS, &success);
        if (!success)
        {
            glGetShaderInfoLog(vertex, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        };

        //  整一个片元着色器
        fragment = glCreateShader(GL_FRAGMENT_SHADER);
        //  把顶点着色器源码附着到刚创建的这个顶点着色器上  编译
        glShaderSource(fragment, 1, &fragmentSource, NULL);
        glCompileShader(fragment);  //  为了能够让OpenGL使用,必须在运行时动态编译它的源码
        //  打印编译错误(如果有的话)
        glGetShaderiv(fragment, GL_COMPILE_STATUS, &success);  //  拿到编译状态
        if (!success)
        {
            glGetShaderInfoLog(fragment, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::VERTEX::COMPILATION_FAILED\n" << infoLog << std::endl;
        }

        // 着色器程序
        if (this->Program == NULL) {
            this->Program = glCreateProgram();
        }
        glAttachShader(this->Program, vertex);
        glAttachShader(this->Program, fragment);
        glLinkProgram(this->Program);
        // 打印连接错误(如果有的话)
        glGetProgramiv(this->Program, GL_LINK_STATUS, &success);
        if (!success)
        {
            glGetProgramInfoLog(this->Program, 512, NULL, infoLog);
            std::cout << "ERROR::SHADER::PROGRAM::LINKING_FAILED\n" << infoLog << std::endl;
        }

        // 删除着色器,它们已经链接到我们的程序中了,已经不再需要了
        glDetachShader(this->Program, vertex);
        glDeleteShader(vertex);
        glDetachShader(this->Program, fragment);
        glDeleteShader(fragment);
    }

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐