簡體   English   中英

SDL/OpenGL 雙緩沖 Memory 泄漏

[英]SDL/OpenGL Double Buffering Memory Leak

所以我一直在嘗試使用 SDL 和 OpenGL 為游戲制作自己的迷你引擎,主要游戲邏輯包含在 singleton class 中。 但是對於我的生活,我無法弄清楚我是如何使用引擎的這個示例部分得到 memory 泄漏的,盡管我很確定它在我調用 SDL_GL_SwapBuffers 時會發生。 每隔兩三秒泄漏大約 4 K。 我正在使用 SDL 1.3; 請幫我找出漏洞,過去一周這讓我發瘋了!

主模塊.h

#ifndef MAINMODULE_H
#define MAINMODULE_H

/// Includes
#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#include <string>

/// Define Statements (Screen elements)
#define MAINMODULE_WIDTH 800
#define MAINMODULE_HEIGHT 600
#define MAINMODULE_CAPTION "MainModule"

/// Define Statements (OpenGL memory usage)
#define MAINMODULE_RED_SIZE 8
#define MAINMODULE_GREEN_SIZE 8
#define MAINMODULE_BLUE_SIZE 8
#define MAINMODULE_ALPHA_SIZE 8
#define MAINMODULE_BUFFER_SIZE 32
#define MAINMODULE_DEPTH_SIZE 16
#define MAINMODULE_DOUBLEBUFFER 1 // 1 to Enable
#define MAINMODULE_FLAGS SDL_OPENGL

/// Define Statements (OpenGL elements)
#define MAINMODULE_CLEARCOLOR 1.0f, 1.0f, 1.0f, 1.0f
#define MAINMODULE_SHADEMODEL GL_SMOOTH
#define MAINMODULE_DEPTH_TEST 0 // 1 to Enable

class MainModule {

    private: // Constructor/Deconsctuctor

        MainModule();
        ~MainModule();

    private: // Class Variables

        static MainModule* _Instance;       // Singleton instance of the module.

        static int _Width;                  // Width of the game screen.
        static int _Height;                 // Height of the game screen.
        static std::string _Caption;        // Game screen caption/title.
        static SDL_Surface* _ScreenSurface; // Game screen as represented by the window.
        static SDL_Event* _Event;   // Events such as mouse/key input.

        static bool _IsInitialized;         // Has the engine been initialized?
        static bool _IsRunning;             // Is the engine running?

    public: // Get/Set Functions

        static inline int Width() { return _Width; }
        static inline int Height() { return _Height; }
        static inline std::string Caption() { return _Caption; }

        static inline bool IsInitialized() { return _IsInitialized; }
        static inline bool IsRunning() { return _IsRunning; }

        static void SetCaption(std::string caption);

    public: // Class Functions

        static void ConstructInstance();
        static void DeconstructInstance();

        static void InitializeModule();
        static void RunGameLogic();                         // Updates and renders game information.

};

#endif // MAINMODULE_H

主模塊.ccp

/// Includes
#include "MainModule.h"
#include <iostream>

// Static Variable Declarations
MainModule* MainModule::_Instance = 0;
int MainModule::_Width = MAINMODULE_WIDTH;
int MainModule::_Height = MAINMODULE_HEIGHT;
std::string MainModule::_Caption = MAINMODULE_CAPTION;
SDL_Surface* MainModule::_ScreenSurface = 0;
SDL_Event* MainModule::_Event = 0;
bool MainModule::_IsInitialized = false;
bool MainModule::_IsRunning = false;

/// Constructor/Deconstructor
MainModule::MainModule() { }

MainModule::~MainModule() { 
    if (_Event != 0) delete _Event;
    if (_ScreenSurface != 0) SDL_FreeSurface(_ScreenSurface);
    SDL_Quit();
}

/// Set Functions
void MainModule::SetCaption(std::string caption)
{ _Caption = caption; if (_IsInitialized) SDL_WM_SetCaption(_Caption.c_str(), 0); }

/// Class Functions
void MainModule::ConstructInstance()
{ if (_Instance == 0) _Instance = new MainModule(); }

void MainModule::DeconstructInstance()
{ if (_Instance != 0) { delete _Instance; _Instance = 0; } }

void MainModule::InitializeModule() {
    ConstructInstance(); // Create an instance if the ConstructInstance function wasn't created before.
    if (_Instance == 0) { printf("MainModule instance not created properly./n"); return; } 

    // Initialize SDL.
    if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { printf("SDL Initialization error: %s/n", SDL_GetError()); return; }

    // Set OpenGL memory usage.
    SDL_GL_SetAttribute(SDL_GL_RED_SIZE, MAINMODULE_RED_SIZE);
    SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, MAINMODULE_GREEN_SIZE);
    SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, MAINMODULE_BLUE_SIZE);
    SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, MAINMODULE_ALPHA_SIZE);
    SDL_GL_SetAttribute(SDL_GL_BUFFER_SIZE, MAINMODULE_BUFFER_SIZE);
    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, MAINMODULE_DEPTH_SIZE);
    SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, MAINMODULE_DOUBLEBUFFER);

    // Creates the screen and window.
    _ScreenSurface = SDL_SetVideoMode(MAINMODULE_WIDTH, MAINMODULE_HEIGHT, MAINMODULE_BUFFER_SIZE, MAINMODULE_FLAGS);
    if (_ScreenSurface == 0) { printf("ScreenSurface not created properly./n"); return; }
    SDL_WM_SetCaption(_Caption.c_str(), 0);

    (MAINMODULE_DEPTH_TEST == 1) ? glEnable(GL_DEPTH_TEST) : glDisable(GL_DEPTH_TEST);

    glClearColor(MAINMODULE_CLEARCOLOR);
    glShadeModel(GL_SMOOTH);

    _IsInitialized = true;
    _IsRunning = true;
    _Event = new SDL_Event();
}

void MainModule::RunGameLogic() {
    while (SDL_PollEvent(_Event)) { // Event handling loop
        switch (_Event->type) {
            case SDL_QUIT: // Exits out of game
            { _IsRunning = false; break; }
            case SDL_ACTIVEEVENT:
            { break; }
            case SDL_KEYDOWN: // Keyboard press down
            { break; }
            case SDL_KEYUP: // Keyboard press up
            { break; }
            case SDL_MOUSEMOTION: // Mouse movement
            { break; }
            case SDL_MOUSEBUTTONDOWN: // Mouse button down
            { break; }
            case SDL_MOUSEBUTTONUP: // Mouse button up
            { break; }
        }
    }

    // Rendering logic
    (MAINMODULE_DEPTH_TEST == 1) ? glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) : glClear(GL_COLOR_BUFFER_BIT);

    SDL_GL_SwapBuffers();
}

/// Entry point for the program
int main(int argc, char** argv) {
    MainModule::InitializeModule();
    if (MainModule::IsInitialized()) { // If the modules initialized sucessfully
        while (MainModule::IsRunning()) { MainModule::RunGameLogic(); }
    }
    MainModule::DeconstructInstance();

    return 0;
}

一般來說,這類問題與底層 OpenGL 庫、編譯器或類似的東西有關 - 像這樣的圖形代碼因有點錯誤和挑剔而臭名昭著

如果您提供更多詳細信息,我可能會提供更多幫助 - 什么操作系統、編譯器、圖形驅動程序/版本、要構建的特定 SDL 版本等。

同時,考慮在另一個操作系統下編譯,看看會發生什么,或者換掉 SDL 版本。

但是,是的,幾乎可以肯定你沒有做錯任何事......

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM