C++ OpenGL memory leak
首先,我是 c 的初学者。
我正在编写自己的游戏引擎。
代码如下。
Sprite.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #include"Sprite.h" Sprite::Sprite(GLfloat x, GLfloat y, GLfloat width, GLfloat height, Shader& shader, char *texturePath) { init(x, y, width, height, shader, texturePath, STBI_rgb_alpha); } Sprite::Sprite(GLfloat x, GLfloat y, GLfloat width, GLfloat height, Shader& shader, char *texturePath, int reg_comp) { init(x, y, width, height, shader, texturePath, reg_comp); } void Sprite::init(GLfloat x, GLfloat y, GLfloat width, GLfloat height, Shader& shader, char *texturePath, int reg_comp) { this->shader = &shader; GLfloat vertices[] = { width/2+x, height/2+y, 0.0f, /* Top Right */ 1.0f, 1.0f, width/2 + x, -height / 2 + y, 0.0f, /* Bottom Right*/ 1.0f, 0.0f, -width/2 + x, -height / 2 + y, 0.0f, /* Bottom Left*/ 0.0f, 0.0f, -width / 2 + x, height / 2 + y, 0.0f, /* Top Left */ 0.0f, 1.0f }; GLuint indices[] = { 0, 1, 3, // 1 1, 2, 3 // 2 }; glGenVertexArrays(1, &VAO); glGenBuffers(1, &VBO); glGenBuffers(1, &EBO); glBindVertexArray(VAO); glBindBuffer(GL_ARRAY_BUFFER, VBO); glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW); //Position glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)0); glEnableVertexAttribArray(0); // TexCoord glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat))); glEnableVertexAttribArray(1); glBindBuffer(GL_ARRAY_BUFFER, 0); glBindVertexArray(0); texture = new Texture(texturePath, reg_comp); transformShaderLocation = glGetUniformLocation(shader.program,"transform"); glProgramUniform4fv(shader.program, transformShaderLocation, 1, transform); } Sprite::~Sprite() { delete texture; } void Sprite::Draw() { glBindTexture(GL_TEXTURE_2D, texture->texture); //? //glUniform1i(glGetUniformLocation(shader->program,"ourTexture"), 0); //? shader->Use(); glBindVertexArray(VAO); glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0); glBindVertexArray(0); } void Sprite::Transform(int x, int y) { glProgramUniform4fv(shader->program, transformShaderLocation, 1, transform); } void Sprite::setTexture(Texture *texture) { delete this->texture; this->texture = texture; } |
Sprite.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #pragma once #include <GL/glew.h> #include"Shader.h" #include <glm/glm.hpp> #include"Texture.h" #include <stb_image.h> class Sprite { public: Sprite(GLfloat x, GLfloat y, GLfloat width, GLfloat height, Shader& shader, char *texturePath); Sprite(GLfloat x, GLfloat y, GLfloat width, GLfloat height, Shader& shader, char *texturePath, int reg_comp); ~Sprite(); void Draw(); void Transform(int x, int y); void setTexture(Texture *texture); private: void init(GLfloat x, GLfloat y, GLfloat width, GLfloat height, Shader& shader, char *texturePath, int reg_comp); GLuint VBO = 0, VAO = 0, EBO = 0; GLint transformShaderLocation; Shader* shader; GLfloat transform[4] = { 1.f, 1.f, 1.f, 1.f }; Texture *texture; }; |
纹理.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | #include"Texture.h" Texture::Texture(char *texturePath, int reg_comp) { glGenTextures(1, &texture); int _width, _height, _ImageComponents; unsigned char *image = stbi_load(texturePath, &_width, &_height, &_ImageComponents, reg_comp); if (image == nullptr) { std::cout <<"error loading image" << std::endl; } glBindTexture(GL_TEXTURE_2D, texture); // Set our texture parameters glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); // Set texture filtering glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); //glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); if (_ImageComponents == 3) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _width, _height, 0, GL_RGB, GL_UNSIGNED_BYTE, image); else if (_ImageComponents == 4) glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, _width, _height, 0, GL_RGBA, GL_UNSIGNED_BYTE, image); //RGBA8? glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); stbi_image_free(image); } Texture::~Texture() { } |
纹理.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | #pragma once #include <GL/glew.h> #include <iostream> #include <stb_image.h> class Texture { public: Texture(char *texturePath, int reg_comp); ~Texture(); GLuint texture = 0; }; |
main.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | #include"main.h" #define STB_IMAGE_IMPLEMENTATION #include <stb_image.h> int main(int argc, char* argv[]) { Main main; return main.init(); } int Main::init() { display = new Display( 800, 600,"OpenGL" ); shader = new Shader("Shaders/default.vert","Shaders/default.frag"); sprite = new Sprite(-0.5f, -0.5f, 1.0f, 1.0f, *shader,"Textures/texture1.png"); sprite2 = new Sprite(0.5f, 0.5f, 1.0f, 1.0f, *shader,"Textures/texture2.png", STBI_rgb); while (!display->isClosed()) { update(); } delete display; delete shader; delete sprite; delete sprite2; return 0; } void Main::update() { draw(); display->Update(); if (debug == 0) { texture->setTexture(new Texture("Textures/texture1.png", STBI_rgb_alpha)); debug = 1; } else if (debug == 1) { texture->setTexture(new Texture("Textures/texture2.png", STBI_rgb)); debug = 0; } } void Main::draw() { glClearColor(0.0f, 0.3f, 0.5f, 1.0f); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);; sprite->Draw(); sprite->Draw(); } |
main.h:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #pragma once #include <iostream> #include"Display.h" #include"Shader.h" #include"Triangle.h" #include"Sprite.h" class Main { public: int init(); private: void draw(); void update(); Display *display; Shader *shader; Triangle *triangle, *triangle2; Sprite *sprite, *sprite2; int debug = 0; }; |
您会看到,每次创建新纹理时,都会删除最后一个纹理。
但是,如果我打开任务管理器,内存使用量就会上升。
为什么呢?
(如果我删除 setTexture(new...) 一切都很好,所以这就是问题所在。
你的
当我编写 OpenGL 的东西时,我现在在所有句柄周围使用package器。如果您使用 GLuint,很可能会忘记一些设置或删除代码。根据您的编码技能,这些package器可能非常通用,或者您可以为此目的使用共享指针。