Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ SDL_GL_SwapBuffers()间歇性变慢_C++_Opengl_Sdl - Fatal编程技术网

C++ SDL_GL_SwapBuffers()间歇性变慢

C++ SDL_GL_SwapBuffers()间歇性变慢,c++,opengl,sdl,C++,Opengl,Sdl,我有一个sdl/opengl游戏,我正在玩。平均来说,我会得到一个不错的fps,但运动真的很不平稳,因为SDL_GL_SwapBuffers()将随机花费很长时间来处理。加载纹理并写入缓冲区时,有时需要超过100毫秒!我删掉了很多代码,试图找出是不是我做错了什么,但运气不太好。当我运行这个裸体程序时,它有时仍会阻塞70毫秒 主要内容: 我开始觉得我可能有硬件问题?不过,我从来没有在游戏中遇到过这种问题。SDL确实使用了SwapIntervalEXT扩展,因此您可以确保缓冲区交换尽可能快(VSYN

我有一个sdl/opengl游戏,我正在玩。平均来说,我会得到一个不错的fps,但运动真的很不平稳,因为SDL_GL_SwapBuffers()将随机花费很长时间来处理。加载纹理并写入缓冲区时,有时需要超过100毫秒!我删掉了很多代码,试图找出是不是我做错了什么,但运气不太好。当我运行这个裸体程序时,它有时仍会阻塞70毫秒

主要内容:


我开始觉得我可能有硬件问题?不过,我从来没有在游戏中遇到过这种问题。

SDL确实使用了
SwapIntervalEXT
扩展,因此您可以确保缓冲区交换尽可能快(VSYNC已禁用)。此外,缓冲区交换不是一个简单的操作,OpenGL需要将后缓冲区的内容复制到前缓冲区,以防您想要
glReadPixels()
。可以使用
WGL\u ARB\u pixel\u format
、使用
WGL\u SWAP\u EXCHANGE\u ARB
来控制这种行为(您可以在规范中阅读所有这些内容;现在我不确定Linux是否有替代方案)

除此之外,还有一个窗口系统。这实际上会造成很多麻烦。另外,如果生成了一些错误

如果您在小型移动GPU上运行,这种行为可能是正常的


SDL\u GL\u SwapBuffers()
只包含对
glxSwapBuffers()
/
wglSwapBuffers()
的调用,因此没有在其中花费时间。

是否启用了任何vsync?不,在阅读本文之后我不这么认为-我想可能发生的事情是调用SwapBuffers()如果不给它处理时间,可能会导致它挂起或循环。我会多读一些书,看看我是否能找到支持这一点的东西。a
SDL\u延迟(1)
在缓冲区交换后,查看它对帧时间的影响。虽然不是完美的,但显著改善。我还注意到部分抖动是因为当屏幕移动时,一帧被复制。谢谢它之所以被命名为“交换”缓冲区,正是因为没有一个健全的实现真正执行复制。@BenVoigt很好,很明显WGL确实读过(不过我并不反对你关于健全性的评论)。这背后的原因是即使在交换之后也能够读取缓冲区的内容(不确定为什么有人想要这样做),这是默认行为。通过启用
WGL\u SWAP\u EXCHANGE\u ARB
您承认您理解在交换之后,缓冲区将交换,您将无法再获取数据。您确定不必明确请求在缓冲区中保留有效数据吗?该
WGL\u SWAP\u METHOD\u ARB
参数有三个选项,它不清楚哪一个是默认值。@BenVoigt你说得对,看它,它不清楚。然而,在NVIDIA的一些优化指南中,他们非常清楚地指出,需要显式设置。
// 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()
{
    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;
}