nvidia opengl framebuffer对象强制vsync on

时间:2015-03-11 20:13:28

标签: c opengl nvidia framebuffer quake

基本上我将伽玛校正实施到基于q3的游戏中,以摆脱恼人的SetDeviceGammaRamp

我正在使用GL_EXT_framebuffer_object作为后期处理顶点着色器。 它工作得很好,除了它在nvidia gpus上有一些奇怪的行为: 它强制启用vsync,除非在控制面板中明确禁用它。 如果我使用标准控制面板的设置并启用了帧缓冲,则强制使用vsync,但如果我删除帧缓冲,则会恢复正常行为。

  • wglSwapIntervalEXT什么都不做
  • 我在nvidia移动GPU上进行了测试,有人可以在桌面GPU上重现它
  • 我还测试了一个集成的intel gpu和两个不同的amd gpu,所有这些都没有问题。

初始化:(我猜不相关)

// ouned: gamma correction
const char *g_GammaVertexShaderARB = {
    "void main(void)" "\n"
    "{" "\n"
        "gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;" "\n"
        "gl_TexCoord[0] = gl_MultiTexCoord0;"  "\n"
    "}"
};

const char *g_GammaFragmentShaderARB = {
    "uniform sampler2D sceneBuffer;" "\n"
    "uniform float gamma;" "\n"
    "\n"
    "void main(void)" "\n"
    "{" "\n"
        "vec2 uv = gl_TexCoord[0].xy;" "\n"
        "vec3 color = texture2D(sceneBuffer, uv).rgb;" "\n"
        "if (uv.x<0.50)" "\n"
            "gl_FragColor.rgb = pow(color, vec3(1.0 / 1.5));" "\n"
        "else" "\n"
            "gl_FragColor.rgb = color;" "\n"
        "gl_FragColor.a = 1.0;" "\n"
    "}"
};

    tr.m_hVShader = qglCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
    qglShaderSourceARB(tr.m_hVShader, 1, (const GLcharARB **)&g_GammaVertexShaderARB, NULL);
    qglCompileShaderARB(tr.m_hVShader);

    if (qglGetError() != GL_NO_ERROR) {
        ri.Printf(PRINT_ERROR, "Failed compiling gamma vertrex shader\n");
    }

    tr.m_hFShader = qglCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
    qglShaderSourceARB(tr.m_hFShader, 1, (const GLcharARB **)&g_GammaFragmentShaderARB, NULL);


    qglCompileShaderARB(tr.m_hFShader);

    if (qglGetError() != GL_NO_ERROR) {
        ri.Printf(PRINT_ERROR, "Failed compiling gamma fragment shader\n");
    }

    tr.gammaProgram = qglCreateProgramObjectARB();
    qglAttachObjectARB(tr.gammaProgram, tr.m_hVShader);
    qglAttachObjectARB(tr.gammaProgram, tr.m_hFShader);
    qglLinkProgramARB(tr.gammaProgram);

    if (qglGetError() != GL_NO_ERROR) {
        ri.Printf(PRINT_ERROR, "Failed linking shaders\n");
    }

    qglUseProgramObjectARB(tr.gammaProgram);

    tr.gammaUniformLoc = qglGetUniformLocationARB(tr.gammaProgram, "gamma");
    tr.gammaSceneBufferLoc = qglGetUniformLocationARB(tr.gammaProgram, "sceneBuffer");

    qglValidateProgramARB(tr.gammaProgram);
    qglUseProgramObjectARB(0);

    // framebuffer object
    tr.gammaFramebuffer = 0;
    qglGenFramebuffersEXT(1, &tr.gammaFramebuffer);
    qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tr.gammaFramebuffer);

    // depth buffer
    tr.gammaRenderDepthBuffer = 0;
    qglGenRenderbuffersEXT(1, &tr.gammaRenderDepthBuffer);
    qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, tr.gammaRenderDepthBuffer);
    qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, glConfig.vidWidth, glConfig.vidHeight);

    tr.gammaRenderTarget = 0;
    qglGenTextures(1, &tr.gammaRenderTarget);
    qglBindTexture(GL_TEXTURE_2D, tr.gammaRenderTarget);
    qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, glConfig.vidWidth, glConfig.vidHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, 0);
    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    qglGenerateMipmapEXT(GL_TEXTURE_2D);

    qglBindTexture(GL_TEXTURE_2D, 0);
    qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, tr.gammaRenderTarget, 0);
    qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, tr.gammaRenderDepthBuffer);

    qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);

在框架的开头:

    qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, tr.gammaFramebuffer);
    qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, tr.gammaRenderDepthBuffer);
    qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);

在框架的末尾:

    qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);

    if (!backEnd.projection2D) {
        qglViewport(0, 0, glConfig.vidWidth, glConfig.vidHeight);
        qglScissor(0, 0, glConfig.vidWidth, glConfig.vidHeight);
        qglMatrixMode(GL_PROJECTION);
        qglLoadIdentity();
        qglOrtho(0, glConfig.vidWidth, glConfig.vidHeight, 0, 0, 1);
        qglMatrixMode(GL_MODELVIEW);
        qglLoadIdentity();

        GL_State(GLS_DEPTHTEST_DISABLE);
    }

    qglUseProgramObjectARB(tr.gammaProgram);
    qglEnable(GL_TEXTURE_2D);

    qglUniform1iARB(tr.gammaSceneBufferLoc, 0);

    qglColor3f(tr.identityLight, tr.identityLight, tr.identityLight);
    qglActiveTextureARB(GL_TEXTURE0);
    qglBindTexture(GL_TEXTURE_2D, tr.gammaRenderTarget);

    qglBegin(GL_QUADS);
    qglTexCoord2f(0, 1);
    qglVertex2f(0, 0);
    qglTexCoord2f(1, 1);
    qglVertex2f(glConfig.vidWidth, 0);
    qglTexCoord2f(1, 0);
    qglVertex2f(glConfig.vidWidth, glConfig.vidHeight);
    qglTexCoord2f(0, 0);
    qglVertex2f(0, glConfig.vidHeight);
    qglEnd();

    qglUseProgramObjectARB(0);

那么,还有什么可以导致启用vsync?

0 个答案:

没有答案