0
\$\begingroup\$

So my problem is that When I make a Shader variable and I swap between mainmenustate and gamestate really fast I notice my memory usage increase alot but as soon I switch my Shader varaible into a pointer memory usage dont increase until I put cameraShader = new Shader(); I tried deleting the cameraShader but memory usage still increase

BAREBONE EXAMPLE

#include "glfw.h"
#include "glad.h"
#include "Shader.h"
class State{
private:
Shader* cameraShader;
public:
State(glfwwindow* window, std::stack<State*>* states){

cameraShader("example.vs", "example.fs");
}
virtual ~State(){
delete cameraShader;
}
}
void update(float& dt){
}

void render(){
}

main

  #include "State.h"
  #include "stdafx.h" 
  #include "Game.h"


  void Game::framebufferCallback(GLFWwindow* window, int width, int height)
  {
  glViewport(0, 0, width, height);
  }

  Game::Game()
  :previousTime(0.f), dt(0.f)
  {
  //Variables
  const unsigned int width = 854, height = 480;

  //Initiating GLFW Window
  glfwInit();
  glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
  glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 6);
  glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
  #ifdef _APPLE_
  glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
  #endif

  //Creating a GLFW window
  window = glfwCreateWindow(width, height, "EXAMPLE", NULL, NULL);

  //Checking if Window was initiated
  if (window == NULL) {
    std::cout << "GLFW FAILED TO INITIATE WINDOW!\n";
    glfwTerminate();
    }

  glfwMakeContextCurrent(window);

  //Setting Window's aspect ratio
  glfwSetWindowAspectRatio(window, 16, 9);

  //Centering Window 
  int windowWidth, windowHeight;
  glfwGetWindowSize(window, &windowWidth, &windowHeight);
  const GLFWvidmode* mode = glfwGetVideoMode(glfwGetPrimaryMonitor());
  glfwSetWindowPos(window, mode->width / 2 - windowWidth / 2, mode->height / 
  2 - windowHeight / 2);



  //Checking if Glad was initiated
  if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
    std::cout << "GLAD FAILED TO BE INITIATED\n";
    }

  //Enabling OpenGl features
  glEnable(GL_CULL_FACE);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glEnable(GL_BLEND);
  glEnable(GL_STENCIL_TEST);
  glEnable(GL_DEPTH_TEST);

  stbi_set_flip_vertically_on_load(true);
  //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

 //Setting-Up Viewport
 glfwSetFramebufferSizeCallback(window, framebufferCallback);

//Intitiating MainMenu
 states.push(new MainMenuState(window, &states));
 }

 Game::~Game()
{
}

int Game::glfwGetWindowShouldClose()
{
return glfwWindowShouldClose(window);
}

void Game::processWindowEvents()
{
//Calculating Deltatime
double currentTime = glfwGetTime();
dt = currentTime - previousTime;
previousTime = currentTime;
}

void Game::update()
{
processWindowEvents();
if (!states.empty()) {

    states.top()->update(dt);
    if (states.top()->getQuit()) {
        states.top()->endstate();
        delete states.top();
        states.pop();
        std::cout << "States has been deleted\n";
    }
}
else {
    glfwSetWindowShouldClose(window, GL_TRUE);
}
}

void Game::render()
{
//Clearing display
glClearColor(0.15f, .45f, .60f, 1.f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

if (!states.empty()) {
    states.top()->render();
}

glfwSwapBuffers(window);
glfwPollEvents();
}

Shader class

#ifndef SHADER_H
#define SHADER_H

#include <glad/glad.h>
#include <glm/glm.hpp>

#include <string>
#include <fstream>
#include <sstream>
#include <iostream>

class Shader
 {
  public:
 unsigned int ID;

 Shader(const char* vertexPath, const char* fragmentPath, const char* geometryPath = nullptr)
 {
    // 1. retrieve the vertex/fragment source code from filePath
    std::string vertexCode;
    std::string fragmentCode;
    std::string geometryCode;
    std::ifstream vShaderFile;
    std::ifstream fShaderFile;
    std::ifstream gShaderFile;
    // ensure ifstream objects can throw exceptions:
    vShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
    fShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
    gShaderFile.exceptions (std::ifstream::failbit | std::ifstream::badbit);
    try 
    {
        // open files
        vShaderFile.open(vertexPath);
        fShaderFile.open(fragmentPath);
        std::stringstream vShaderStream, fShaderStream;
        // read file's buffer contents into streams
        vShaderStream << vShaderFile.rdbuf();
        fShaderStream << fShaderFile.rdbuf();       
        // close file handlers
        vShaderFile.close();
        fShaderFile.close();
        // convert stream into string
        vertexCode = vShaderStream.str();
        fragmentCode = fShaderStream.str();         
        // if geometry shader path is present, also load a geometry shader
        if(geometryPath != nullptr)
        {
            gShaderFile.open(geometryPath);
            std::stringstream gShaderStream;
            gShaderStream << gShaderFile.rdbuf();
            gShaderFile.close();
            geometryCode = gShaderStream.str();
        }
    }
    catch (std::ifstream::failure& e)
    {
        std::cout << "ERROR::SHADER::FILE_NOT_SUCCESFULLY_READ" << std::endl;
    }
    const char* vShaderCode = vertexCode.c_str();
    const char * fShaderCode = fragmentCode.c_str();
    // 2. compile shaders
    unsigned int vertex, fragment;
    // vertex shader
    vertex = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertex, 1, &vShaderCode, NULL);
    glCompileShader(vertex);
    checkCompileErrors(vertex, "VERTEX");
    // fragment Shader
    fragment = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragment, 1, &fShaderCode, NULL);
    glCompileShader(fragment);
    checkCompileErrors(fragment, "FRAGMENT");
    // if geometry shader is given, compile geometry shader
    unsigned int geometry;
    if(geometryPath != nullptr)
    {
        const char * gShaderCode = geometryCode.c_str();
        geometry = glCreateShader(GL_GEOMETRY_SHADER);
        glShaderSource(geometry, 1, &gShaderCode, NULL);
        glCompileShader(geometry);
        checkCompileErrors(geometry, "GEOMETRY");
    }
    // shader Program
    ID = glCreateProgram();
    glAttachShader(ID, vertex);
    glAttachShader(ID, fragment);
    if(geometryPath != nullptr)
        glAttachShader(ID, geometry);
    glLinkProgram(ID);
    checkCompileErrors(ID, "PROGRAM");
    // delete the shaders as they're linked into our program now and no longer necessery
    glDeleteShader(vertex);
    glDeleteShader(fragment);
    if(geometryPath != nullptr)
        glDeleteShader(geometry);

}
// activate the shader
// ------------------------------------------------------------------------
void use() 
{ 
    glUseProgram(ID); 
}
// utility uniform functions
// ------------------------------------------------------------------------
void setBool(const std::string &name, bool value) const
{         
    glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value); 
}
// ------------------------------------------------------------------------
void setInt(const std::string &name, int value) const
{ 
    glUniform1i(glGetUniformLocation(ID, name.c_str()), value); 
}
// ------------------------------------------------------------------------
void setFloat(const std::string &name, float value) const
{ 
    glUniform1f(glGetUniformLocation(ID, name.c_str()), value); 
}
// ------------------------------------------------------------------------
void setVec2(const std::string &name, const glm::vec2 &value) const
{ 
    glUniform2fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); 
}
void setVec2(const std::string &name, float x, float y) const
{ 
    glUniform2f(glGetUniformLocation(ID, name.c_str()), x, y); 
}
// ------------------------------------------------------------------------
void setVec3(const std::string &name, const glm::vec3 &value) const
{ 
    glUniform3fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); 
}
void setVec3(const std::string &name, float x, float y, float z) const
{ 
    glUniform3f(glGetUniformLocation(ID, name.c_str()), x, y, z); 
}
// ------------------------------------------------------------------------
void setVec4(const std::string &name, const glm::vec4 &value) const
{ 
    glUniform4fv(glGetUniformLocation(ID, name.c_str()), 1, &value[0]); 
}
void setVec4(const std::string &name, float x, float y, float z, float w) 
{ 
    glUniform4f(glGetUniformLocation(ID, name.c_str()), x, y, z, w); 
}
// ------------------------------------------------------------------------
void setMat2(const std::string &name, const glm::mat2 &mat) const
{
    glUniformMatrix2fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat3(const std::string &name, const glm::mat3 &mat) const
{
    glUniformMatrix3fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}
// ------------------------------------------------------------------------
void setMat4(const std::string &name, const glm::mat4 &mat) const
{
    glUniformMatrix4fv(glGetUniformLocation(ID, name.c_str()), 1, GL_FALSE, &mat[0][0]);
}

private:
// utility function for checking shader compilation/linking errors.
// ------------------------------------------------------------------------
void checkCompileErrors(GLuint shader, std::string type)
{
    GLint success;
    GLchar infoLog[1024];
    if(type != "PROGRAM")
    {
        glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
        if(!success)
        {
            glGetShaderInfoLog(shader, 1024, NULL, infoLog);
            std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog;
        }
    }
    else
    {
        glGetProgramiv(shader, GL_LINK_STATUS, &success);
        if(!success)
        {
            glGetProgramInfoLog(shader, 1024, NULL, infoLog);
            std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog;
        }
    }
}
};
    #endif
\$\endgroup\$
1
  • \$\begingroup\$ Could it be that your Shader class is missing a dtor with a call to glDeleteProgram? \$\endgroup\$ – Vaillancourt Dec 24 '20 at 12:40
1
\$\begingroup\$

Shader need a:

  1. Copy constructor
  2. Move constructor
  3. Copy assignment operator
  4. Move assignment operator
  5. Destructor

For stop leak videocard memory. You call glCreateXxxx and you should call glDeleteXxxx on destruction. https://khronos.org/registry/OpenGL-Refpages/gl4/

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.