我的JS代码:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var mouse = {x:0,y:0}
const times = [];
let fps;
function refreshLoop() {
window.requestAnimationFrame(() => {
const now = performance.now();
while (times.length > 0 && times[0] <= now - 1000) {
times.shift();
}
times.push(now);
fps = times.length;
refreshLoop();
});
}
refreshLoop();
function draw() {
ctx.fillStyle = "black"
ctx.fillRect(0, 0, c.width, c.height);
ctx.strokeStyle = "white"
ctx.beginPath();
var e = window.event;
ctx.arc(mouse.x, mouse.y, 40, 0, 2*Math.PI);
ctx.stroke();
ctx.font = "30px Comic Sans MS"; …Run Code Online (Sandbox Code Playgroud) WGL_EXT_swap_control扩展允许在Windows上执行此操作,但我无法找到任何远程跨平台执行相同操作,即同步我的缓冲区交换与屏幕刷新.我的应用程序使用GLEW,所以提供的东西更可取.对Linux,Mac和Windows的跨平台支持是必要的,但如果无法设置同步,我的应用程序将不会中断(例如,用户已将其强制关闭在其图形驱动程序中).
我将接受程序代码在许多平台上使用GLEW作为有效答案.
我使用以下代码初始化 SDL:
SDL_Init(SDL_INIT_VIDEO);
SDL_Window* win = SDL_CreateWindow(
"SDL Window",
SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED,
WIDTH,
HEIGHT,
SDL_WINDOW_SHOWN
);
SDL_Renderer* ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_SOFTWARE);
SDL_GL_SetSwapInterval(1); // probably has no effect since it's not using GL
Run Code Online (Sandbox Code Playgroud)
然后我使用非 SDL 软件渲染器进行渲染,并使用以下代码将其呈现给窗口:
SDL_UpdateTexture(screenBuffer, NULL, screenData, WIDTH*4);
SDL_RenderClear(ren);
SDL_RenderCopy(ren, screenBuffer, NULL, NULL);
SDL_RenderPresent(ren);
Run Code Online (Sandbox Code Playgroud)
帧率完全没有上限,我不知道为什么。
添加| SDL_RENDERER_PRESENTVSYNC到 SDL_CreateRenderer 标志只会使窗口成为空白的白屏。虽然我需要使用该SDL_RENDERER_SOFTWARE标志(即使我没有使用 SDL 的软件渲染器来呈现屏幕),否则SDL_RenderPresent()会停顿很长时间,导致每秒大约 1 帧。
我怎样才能SDL_RenderPresent()等待 vsync,或者自己(准确地)等待它?
我正在尝试使用 wglSwapIntervalEXT(int Interval) 在 OpenGl 中使用 WGL_EXT_swap_control 禁用垂直同步。
我试图包含 wglext 标头,但经过多次搜索后,它似乎没有安装在我的电脑上(使用 opengl 扩展查看器来找到它)。我已尝试安装Windows sdk并更新.net框架,但仍然无法安装此扩展。
无论如何,有没有包括这个。我的显卡是 nVidia GTX 770m。或者有没有更简单的方法来禁用垂直同步。
谢谢
我不清楚显示面板上垂直空白(vblank )的使用。
有人可以解释一下吗
我拼命想让Vsync在我的OpenGL应用程序中运行.这是至关重要的统计数据:
我正在使用Windows,在C++ OpenGL中编码,我正在使用FreeGLUT进行OpenGL上下文(双缓冲).我知道要让交换缓冲区在Windows中等待垂直同步,你需要调用wglSwapIntervalEXT().
我的代码确实称之为(正如您将在下面看到的那样),但我仍然在进行垂直撕裂.我设法阻止它的唯一方法是调用glFinish(),这当然会带来与之相关的显着性能损失.
main()函数的相关部分如下所示:
//Initiating glut window
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH);
glutInitWindowSize (initial_window_width, initial_window_height);
glutInitWindowPosition (100, 100);
int glut_window_hWnd = glutCreateWindow(window_title.c_str());
//Setting up swap intervals
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT = NULL;
if (WGLExtensionSupported("WGL_EXT_swap_control"))
{
// Extension is supported, init pointers.
wglSwapIntervalEXT = PFNWGLSWAPINTERVALEXTPROC)wglGetProcAddress("wglSwapIntervalEXT");
// this is another function from WGL_EXT_swap_control extension
wglGetSwapIntervalEXT = (PFNWGLGETSWAPINTERVALEXTPROC)wglGetProcAddress("wglGetSwapIntervalEXT");
}
wglSwapIntervalEXT (1)
init ();
glutMainLoop(); ///Starting the glut loop
return(0);
Run Code Online (Sandbox Code Playgroud)
我应该指出wglInitSwapControlARB函数的返回是真的,因此支持扩展.
在游戏中我们的互联网组装团队正在编程,我们假设我们的观众中的每个人都将在游戏中获得全速.
因此,为了节省视频RAM,并希望为显卡提供更多的空闲时间,使用没有双缓冲的V-sync将是我们的最佳选择.因此,在OpenGL中,我们需要知道如何做到这一点.
根据我的理解,V-sync是指图形卡在完成渲染单帧后暂停,直到该帧完成发送到显示设备.双缓冲不会暂停渲染操作(或者可能是暂停渲染操作,或者可能是特定于实现;不确定),因为它会在复制到帧缓冲区之前绘制到第二个缓冲区,以便监视器获得完整帧或不根本就是新帧(具体来说,是帧缓冲区中最后存储的图像).好吧,我们不需要这个功能,只要显卡只是在它需要时才写入帧缓冲区.
这是一个非常慢的在线游戏(但它非常有创意^ _ ^).实时行动非常少.因此,非常精确的用户输入不是必需的; 它可以在渲染帧之前随时从OS捕获为单个单元.
所以,为了做到这一点,我需要能够从OpenGL获得"Frame已经完成发送到监视器"的消息.可能吗?如果没有,最好的选择是什么?
该游戏目前仅针对Windows编程,但应该在几个月内完成Linux的工作.
vsync ×7
opengl ×4
c++ ×3
windows ×2
android ×1
buffering ×1
canvas ×1
freeglut ×1
javascript ×1
linux-kernel ×1
low-latency ×1
message ×1
sdl-2 ×1
windows-10 ×1