6

私は楽しみのために取り組んでいるsdl/openglゲームを持っています。平均してまともなfpsが得られますが、SDL_GL_SwapBuffers()の処理にはランダムに長い時間がかかるため、動きが途切れます。テクスチャがロードされてバッファに書き込まれると、100ミリ秒以上かかる場合があります。私は自分のコードの多くを切り取って、それが自分が間違ったことであるかどうかを判断しようとしましたが、あまり運がありませんでした。このベアボーンプログラムを実行すると、最大70ミリ秒ブロックされることがあります。

主要:

// Don't forget to link to opengl32, glu32, SDL_image.lib

// includes
#include <stdio.h>

// SDL
#include <cstdlib>
#include <SDL/SDL.h>

// Video
#include "videoengine.h"

int main(int argc, char *argv[])
{
    // begin SDL
    if ( SDL_Init(SDL_INIT_VIDEO) != 0 )
    {
        printf("Unable to initialize SDL: %s\n", SDL_GetError());
    }

    // begin video class
    VideoEngine videoEngine;

    // BEGIN MAIN LOOP
    bool done = false;
    while (!done)
    {
        int loopStart = SDL_GetTicks();

        printf("STARTING SWAP BUFFER : %d\n", SDL_GetTicks() - loopStart);
        SDL_GL_SwapBuffers();


        int total = SDL_GetTicks() - loopStart;
        if (total > 6)
            printf("END LOOP  : %d ------------------------------------------------------------>\n", total);
        else
             printf("END LOOP  : %d\n", total);

    }
    // END MAIN LOOP

    return 0;
}

私の「VideoEngine」コンストラクター:

    VideoEngine::VideoEngine()
{
    UNIT = 16;
    SCREEN_X = 320;
    SCREEN_Y = 240;
    SCALE = 1;


    // Begin Initalization

        SDL_Surface *screen;

        SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );  // [!] SDL_GL_SetAttributes must be done BEFORE SDL_SetVideoMode

        screen = SDL_SetVideoMode( SCALE*SCREEN_X, SCALE*SCREEN_Y, 16, SDL_OPENGL );  // Set screen to the window with opengl
        if ( !screen )  // make sure the window was created
        {
            printf("Unable to set video mode: %s\n", SDL_GetError());
        }

        // set opengl state
        opengl_init();

    // End Initalization

}

void VideoEngine::opengl_init()
{
    // Set the OpenGL state after creating the context with SDL_SetVideoMode

        //glClearColor( 0, 0, 0, 0 );                             // sets screen buffer to black
        //glClearDepth(1.0f);                                     // Tells OpenGL what value to reset the depth buffer when it is cleared
        glViewport( 0, 0, SCALE*SCREEN_X, SCALE*SCREEN_Y );     // sets the viewport to the default resolution (SCREEN_X x SCREEN_Y) multiplied by SCALE. (x,y,w,h)
        glMatrixMode( GL_PROJECTION );                          // Applies subsequent matrix operations to the projection matrix stack.
        glLoadIdentity();                                       // Replaces the current matrix with the identity matrix
        glOrtho( 0, SCALE*SCREEN_X, SCALE*SCREEN_Y, 0, -1, 1 ); //describes a transformation that produces a parallel projection
        glMatrixMode( GL_MODELVIEW );                           // Applies subsequent matrix operations to the projection matrix stack.
        glEnable(GL_TEXTURE_2D);                                // Need this to display a texture
        glLoadIdentity();                                       // Replaces the current matrix with the identity matrix
        glEnable(GL_BLEND);                                     // Enable blending for transparency
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);      // Specifies pixel arithmetic
        //glDisable( GL_LIGHTING );                               // Disable lighting
        //glDisable( GL_DITHER );                                 // Disable dithering
        //glDisable( GL_DEPTH_TEST );                             // Disable depth testing

        //Check for error
        GLenum error = glGetError();
        if( error != GL_NO_ERROR )
        {
         printf( "Error initializing OpenGL! %s\n", gluErrorString( error ) );
        }

    return;
}

ハードウェアに問題があるのではないかと考え始めていますか?しかし、私はゲームでこの問題を経験したことはありません。

4

1 に答える 1

2

SDL はSwapIntervalEXT拡張機能を使用するため、バッファー スワップが可能な限り高速であることを確認できます (VSYNC が無効になっています)。また、バッファ スワップは単純な操作ではありません。OpenGL は、必要に応じてバック バッファの内容をフロント バッファにコピーする必要がありますglReadPixels()。この動作はWGL_ARB_pixel_format、 を使用して制御できWGL_SWAP_EXCHANGE_ARBます (仕様でこれらすべてについて読むことができます。Linux 用の代替手段があるかどうかはわかりません)。

その上に、ウィンドウ システムがあります。それは実際に多くの問題を引き起こす可能性があります。また、何らかのエラーが発生する場合は……

小さなモバイル GPU で実行している場合、この動作はおそらく問題ありません。

SDL_GL_SwapBuffers()glxSwapBuffers()/への呼び出しのみが含まれているwglSwapBuffers()ため、そこに費やされる時間はありません。

于 2012-11-09T12:25:07.693 に答える