簡體   English   中英

帶有OpenGL和SDL的圖塊地圖使用率很高

[英]Tile Map Usage Much CPU With OpenGL and SDL

我一直在研究一種使用OpenGL和SDL基於圖塊繪制地圖的方法。 最后我進行了編碼,但是當我執行基本程序時,它繪制了一個25x16的圖塊貼圖,並且檢查了CPU的使用情況,它說消耗了25%的內存,而未繪制該圖則消耗了1%的CPU。

因此存在另一種繪制地圖的方法,或者為什么CPU使用率如此之高。

這是繪制地圖的代碼。

void CMapManager::drawMap(Map *map)
{
    vector<ImagePtr> tempImages = CGameApplication::getInstance()->getGameApp()->getImages();
    GLuint texture = tempImages.at(1)->getTexture();

    glColor3f(1.0f, 1.0f, 1.0f);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    glBindTexture( GL_TEXTURE_2D, texture );
    glBegin( GL_QUADS );

        for (int i = 0; i < map->getHeight(); i++)
        {
            for (int j = 0; j < map->getWidth(); j++)
            {
                ImagePtr imgDraw = tempImages.at(map->getMapTiles()[i][j]->getTypeTile());

                glTexCoord2i( 0, 0 );
                glVertex3f( imgDraw->getPosX() + (imgDraw->getWidth()*j), imgDraw->getPosY() + (imgDraw->getHeight()*i), 0.f );

                //Bottom-left vertex (corner)
                glTexCoord2i( 1, 0 );
                glVertex3f( imgDraw->getOffsetX() + (imgDraw->getWidth()*j), imgDraw->getPosY() + (imgDraw->getHeight()*i), 0.f );

                //Bottom-right vertex (corner)
                glTexCoord2i( 1, 1 );
                glVertex3f( imgDraw->getOffsetX() + (imgDraw->getWidth()*j), imgDraw->getOffsetY() + (imgDraw->getHeight()*i), 0.f );

                //Top-right vertex (corner)
                glTexCoord2i( 0, 1 );
                glVertex3f( imgDraw->getPosX() + (imgDraw->getWidth()*j),  imgDraw->getOffsetY() + (imgDraw->getHeight()*i), 0.f );
            }
        }       

    glEnd();

    glDisable(GL_BLEND);

}

在這種方法中,我調用函數:

void CGameApplication::renderApplication()
{       
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); 
    glEnable(GL_TEXTURE_2D);

    vector<ImagePtr> tempImages = GApp->getImages();
    vector<ImagePtr>::iterator iterImage;

    for (iterImage = tempImages.begin(); iterImage != tempImages.end(); ++iterImage)
    {
        CImageM->drawSprites( (*iterImage)->getTexture(), (*iterImage)->getPosX(), (*iterImage)->getPosY(), 
                            (*iterImage)->getOffsetX(), (*iterImage)->getOffsetY() );
    }

    vector<TextPtr> tempTexts = GApp->getTexts();
    vector<TextPtr>::iterator iterText;

    for (iterText = tempTexts.begin(); iterText != tempTexts.end(); ++iterText)
    {
        CTextM->drawFonts( (*iterText) );
    }

    CMapM->drawMap(GApp->getCurrentMap());

    glDisable(GL_TEXTURE_2D);

}

我已經設置了一個在此功能之后的計時器:

    GameApplication->getCKeyboardHandler()->inputLogic();
    GameApplication->renderApplication();

    SDL_GL_SwapBuffers();

    GameApplication->getGameApp()->getTimer()->delay();

延遲函數為:

void Timer::delay()
{
    if( this->getTicks() < 1000 / FRAMES_PER_SECOND )
    {
        SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - this->getTicks() );
    }
}

const FRAMES_PER_SECOND現在是5。

將圖像轉換為GL紋理的功能是:

GLuint CImageManager::imageToGLTexture(std::string name)
{
    GLuint texture;     
    SDL_Surface *surface;   
    GLenum texture_format;
    GLint  nOfColors;

    if ( (surface = IMG_Load(name.c_str())) ) { 

        // Check that the image's width is a power of 2
        if ( (surface->w & (surface->w - 1)) != 0 ) {
            printf("warning: image.bmp's width is not a power of 2\n");
        }

        // Also check if the height is a power of 2
        if ( (surface->h & (surface->h - 1)) != 0 ) {
            printf("warning: image.bmp's height is not a power of 2\n");
        }

        // get the number of channels in the SDL surface
        nOfColors = surface->format->BytesPerPixel;
        if (nOfColors == 4)     // contains an alpha channel
        {
            if (surface->format->Rmask == 0x000000ff)
                    texture_format = GL_RGBA;
            else
                    texture_format = GL_BGRA_EXT;
        } 

        else if (nOfColors == 3)     // no alpha channel
        {
            if (surface->format->Rmask == 0x000000ff)
                    texture_format = GL_RGB;
            else
                    texture_format = GL_BGR_EXT;
        } 

        else {
            printf("warning: the image is not truecolor..  this will probably break\n");
            // this error should not go unhandled
        }

        SDL_SetAlpha(surface, 0, 0);

        // Have OpenGL generate a texture object handle for us
        glGenTextures( 1, &texture );

        // Bind the texture object
        glBindTexture( GL_TEXTURE_2D, texture );

        // Set the texture's stretching properties
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

        // Edit the texture object's image data using the information SDL_Surface gives us
        glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
                              texture_format, GL_UNSIGNED_BYTE, surface->pixels );
    } 

    else {
        printf("SDL could not load the image: %s\n", SDL_GetError());
        SDL_Quit();
        exit(1);
    }    

    if ( surface ) { 
        SDL_FreeSurface( surface );
    }

    return texture;
}

先謝謝您的幫助。

畢竟,避免狀態更改。 將所有圖塊合並為一個紋理,並僅使用一個glBegin / glEnd塊進行渲染。

如果您不想進行很多更改,請嘗試顯示列表 OpenGL將能夠優化您的調用,但不能保證它將運行得更快。

如果您的地圖變化不大,請使用VBO。 這是最快的方法。

暫無
暫無

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

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