gpt4 book ai didi

c++ - SDL_GL_SwapBuffers() 间歇性变慢

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:44:06 25 4
gpt4 key购买 nike

我正在开发一款 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;
}

我开始怀疑我可能遇到了硬件问题?不过我从来没有遇到过这个问题。

最佳答案

SDL 确实使用了 SwapIntervalEXT扩展,以便您可以确保缓冲区交换尽可能快(禁用 VSYNC)。此外,缓冲区交换不是一个简单的操作,OpenGL 需要将后台缓冲区的内容复制到前台缓冲区,以备不时之需 glReadPixels() .可以使用 WGL_ARB_pixel_format 控制此行为, 使用 WGL_SWAP_EXCHANGE_ARB (您可以在规范中阅读所有这些内容;现在我不确定是否有适用于 Linux 的替代方案)。

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

如果您在小型移动 GPU 上运行,此行为可能没问题。

SDL_GL_SwapBuffers()仅包含对 glxSwapBuffers() 的调用/wglSwapBuffers()所以没有时间在那里度过。

关于c++ - SDL_GL_SwapBuffers() 间歇性变慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12939705/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com