使用帧缓冲和Oculus Rift的空白屏幕

OpenGL - Blank Screen with using Framebuffers and Oculus Rift

本文关键字:Rift 空白 屏幕 Oculus 缓冲      更新时间:2023-10-16

我有下面的代码,试图显示到Oculus Rift,但我得到一个空白屏幕。

没有显示,我不知道为什么。

请注意,我已经省略了一个相当大的项目的部分,但如果你觉得你需要更多的信息来解决这个问题,只是问!

    /*
    Initial Setup here.
    Using OpenGL 3.1 as the project demands backwards compatibility.
    */
    glfwWindowHint(GLFW_SAMPLES, 4); // 4x antialiasing
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); // We want OpenGL 3.1
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_ANY_PROFILE);
    MainApplicationWindow = glfwCreateWindow((*DEFAULT_WINDOW_WIDTH), (*DEFAULT_WINDOW_HEIGHT), MAIN_WINDOW_TITLE, glfwGetPrimaryMonitor(), NULL);
    if (MainApplicationWindow == NULL) {
    glfwTerminate();
    OpenGLInitialized = false;
    return;
    }
    glfwMakeContextCurrent(MainApplicationWindow);
    // Initialize GLEW
    glewExperimental = true; // Needed in core profile
    if (glewInit() != GLEW_OK) {
    OpenGLInitialized = false;
    return;
    }
    /*
    The code that actually compiles the shaders omitted.
    If needed can be produced.
    */
    OpenGLCompileStatus = PrepareShadowMapShaders();
    if (OpenGLCompileStatus != "SUCCESS") {
    OpenGLInitialized = false;
    return;
    }
    /*
    Predefined GLuint.
    */
    glUseProgram(g_StandardShaderProgram_ID);
    /*
    Further down program...
    */
    glfwSetKeyCallback(MainOpenGLController->GetCurrentGLFWWindow(), KeyCallback);
    glfwSetWindowSizeCallback(MainOpenGLController->GetCurrentGLFWWindow(), WindowResizeCallBack);
    /*
    This is how I set up everthing for the framebuffer for the Oculus Rift
    */
    void SetupTheRift() {
    ovr_Initialize();
    CurrentRiftDevice = ovrHmd_Create(0);
    ovrHmd_GetDesc(CurrentRiftDevice, &CurrentRiftDeviceDesc);
    ovrHmd_StartSensor(CurrentRiftDevice, ovrHmdCap_Orientation | ovrHmdCap_YawCorrection |
        ovrHmdCap_Position | ovrHmdCap_LowPersistence | ovrHmdCap_Orientation, 0);
    l_TextureSizeLeft = ovrHmd_GetFovTextureSize(CurrentRiftDevice, ovrEye_Left, CurrentRiftDeviceDesc.DefaultEyeFov[0], 1.0f);
    l_TextureSizeRight = ovrHmd_GetFovTextureSize(CurrentRiftDevice, ovrEye_Right, CurrentRiftDeviceDesc.DefaultEyeFov[1], 1.0f);
    l_TextureSize;
    l_TextureSize.w = l_TextureSizeLeft.w + l_TextureSizeRight.w;
    l_TextureSize.h = (l_TextureSizeLeft.h>l_TextureSizeRight.h ? l_TextureSizeLeft.h : l_TextureSizeRight.h);
    MainRiftDevice = CurrentRiftDevice;
    MainRiftDeviceDesc = CurrentRiftDeviceDesc;
    IsRiftAvailable = true;
    l_TextureSizeLeft = ovrHmd_GetFovTextureSize((*MainRiftDevice), ovrEye_Left, MainRiftDeviceDesc->DefaultEyeFov[ovrEye_Left], 1.0f);
    l_TextureSizeRight = ovrHmd_GetFovTextureSize((*MainRiftDevice), ovrEye_Right, MainRiftDeviceDesc->DefaultEyeFov[ovrEye_Right], 1.0f);
    l_TextureSize.w = l_TextureSizeLeft.w + l_TextureSizeRight.w;
    l_TextureSize.h = std::max(l_TextureSizeLeft.h, l_TextureSizeRight.h);
    glGenFramebuffers(1, &g_OculusRiftFrameBufferObject_ID);
    glBindFramebuffer(GL_FRAMEBUFFER, g_OculusRiftFrameBufferObject_ID);
    glGenTextures(1, &g_OculusRiftTexture_ID);
    glBindTexture(GL_TEXTURE_2D, g_OculusRiftTexture_ID);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, l_TextureSize.w, l_TextureSize.h, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glGenRenderbuffers(1, &g_OculusRiftDepthBufferObject_ID);
    glBindRenderbuffer(GL_RENDERBUFFER, g_OculusRiftDepthBufferObject_ID);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, l_TextureSize.w, l_TextureSize.h);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, g_OculusRiftDepthBufferObject_ID);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, g_OculusRiftTexture_ID, 0);
    GLenum l_GLDrawBuffers[1] = { GL_COLOR_ATTACHMENT0 };
    glDrawBuffers(1, l_GLDrawBuffers); // "1" is the size of DrawBuffers
    g_DrawBufferStatusCheck_ENUM = glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER);
    if (g_DrawBufferStatusCheck_ENUM != GL_FRAMEBUFFER_COMPLETE)
    {
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    return false;
    }
    else
    {
    glBindRenderbuffer(GL_RENDERBUFFER, 0);
    glBindTexture(GL_TEXTURE_2D, 0);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
    MainEyeDesc[ovrEye_Left].Eye = ovrEye_Left;
    MainEyeDesc[ovrEye_Right].Eye = ovrEye_Right;
    MainEyeDesc[ovrEye_Left].Fov = (*MainRiftDeviceDesc).DefaultEyeFov[ovrEye_Left];
    MainEyeDesc[ovrEye_Right].Fov = (*MainRiftDeviceDesc).DefaultEyeFov[ovrEye_Right];
    MainEyeDesc[ovrEye_Left].TextureSize.w = l_TextureSize.w;
    MainEyeDesc[ovrEye_Left].TextureSize.h = l_TextureSize.h;
    MainEyeDesc[ovrEye_Right].TextureSize.w = l_TextureSize.w;
    MainEyeDesc[ovrEye_Right].TextureSize.h = l_TextureSize.h;
    MainEyeDesc[ovrEye_Left].RenderViewport.Pos.x = 0;
    MainEyeDesc[ovrEye_Left].RenderViewport.Pos.y = 0;
    MainEyeDesc[ovrEye_Right].RenderViewport.Pos.x = (l_TextureSize.w + 1) / 2;
    MainEyeDesc[ovrEye_Right].RenderViewport.Pos.y = 0;
    MainEyeDesc[ovrEye_Left].RenderViewport.Size.w = l_TextureSize.w / 2;
    MainEyeDesc[ovrEye_Left].RenderViewport.Size.h = l_TextureSize.h;
    MainEyeDesc[ovrEye_Right].RenderViewport.Size.w = MainEyeDesc[ovrEye_Left].RenderViewport.Size.w;
    MainEyeDesc[ovrEye_Right].RenderViewport.Size.h = MainEyeDesc[ovrEye_Left].RenderViewport.Size.h;
    l_Cfg.OGL.Header.API = ovrRenderAPI_OpenGL;
    l_Cfg.OGL.Header.Multisample = 0;
    l_Cfg.OGL.Header.RTSize.w = (*MainRiftDeviceDesc).Resolution.w;
    l_Cfg.OGL.Header.RTSize.h = (*MainRiftDeviceDesc).Resolution.h;
    l_Cfg.OGL.WglContext = glfwGetWGLContext(MainApplicationWindow);
    l_Cfg.OGL.Window = glfwGetWin32Window(MainApplicationWindow);
    l_Cfg.OGL.GdiDc = GetDC(l_Cfg.OGL.Window);
    int l_RenderCaps = 0;
    int l_DistortionCaps = ovrDistortion_Chromatic | ovrDistortion_TimeWarp;
    if (ovrHmd_ConfigureRendering((*MainRiftDevice), &l_Cfg.Config, l_RenderCaps,
        l_DistortionCaps, MainEyeDesc, MainEyeRenderDesc) == false) {
        return false;
    }
    l_EyeTexture[ovrEye_Left].OGL.Header.API = ovrRenderAPI_OpenGL;
    l_EyeTexture[ovrEye_Left].OGL.Header.TextureSize.w = l_TextureSize.w;
    l_EyeTexture[ovrEye_Left].OGL.Header.TextureSize.h = l_TextureSize.h;
    l_EyeTexture[ovrEye_Left].OGL.Header.RenderViewport = MainEyeDesc[0].RenderViewport;
    l_EyeTexture[ovrEye_Left].OGL.TexId = g_OculusRiftTexture_ID;
    // Right eye uses the same texture, but a different rendering viewport...
    l_EyeTexture[ovrEye_Right] = l_EyeTexture[ovrEye_Left];
    l_EyeTexture[ovrEye_Right].OGL.Header.RenderViewport = MainEyeDesc[ovrEye_Right].RenderViewport;
    return true;
    }
    /*
    Then I load my Geometry.
    Geometry previously loaded from file
    */
    glBindFramebuffer(GL_FRAMEBUFFER, MainOpenGLController->GetOculusRiftFrameBufferObjectID());
    glGenVertexArrays(1, &Pointer_VAO);
    glBindVertexArray(Pointer_VAO);
    // Create Vertex Buffer Object
    glGenBuffers(1, &Vertex_VBO);
    // Save vertex attributes into GPU
    glBindBuffer(GL_ARRAY_BUFFER, Vertex_VBO);
    glBufferData(GL_ARRAY_BUFFER, TotalVertexCount * Vertex_Stride * sizeof(GLfloat), &AllVertices[0], GL_STATIC_DRAW);
    glVertexAttribPointer(Vertex_VBO, Vertex_Stride, GL_FLOAT, GL_FALSE, 0, 0);
    delete[] Vertices;
    if (HasNormals)
    {
    glGenBuffers(1, &Normal_VBO);
    glBindBuffer(GL_ARRAY_BUFFER, Normal_VBO);
    glBufferData(GL_ARRAY_BUFFER, TotalVertexCount * Normal_Stride * sizeof(GLfloat), &AllNormals[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(Normal_VBO);
    glVertexAttribPointer(Normal_VBO, Normal_Stride, GL_FLOAT, GL_FALSE, 0, 0);
    delete[] Normals;
    }
    if (HasUVs)
    {
    glGenBuffers(1, &UV_VBO);
    glBindBuffer(GL_ARRAY_BUFFER, UV_VBO);
    glBufferData(GL_ARRAY_BUFFER, TotalVertexCount * UV_Stride * sizeof(GLfloat), &AllUVs[0], GL_STATIC_DRAW);
    glEnableVertexAttribArray(UV_VBO);
    glVertexAttribPointer(UV_VBO, UV_Stride, GL_FLOAT, GL_FALSE, 0, 0);
    delete[] UVs;
    }
    glGenBuffers(1, &Index_VBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, Index_VBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, TotalPolygonCount * Triangle_Vertex_Count * sizeof(GLuint), &ALLIndices[0], GL_STATIC_DRAW);
    delete[] Indices;
    glBindVertexArray(0);
    /*
    And here is my drawing code.
    */

    ovrFrameTiming m_HmdFrameTiming = ovrHmd_BeginFrame((*MainRiftDevice), 0);
        glBindFramebuffer(GL_FRAMEBUFFER, g_OculusRiftFrameBufferObject_ID);
        glClearColor(0.2f, 0.3f, 0.4f, 1.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        //glEnable(GL_CULL_FACE);
        //glEnable(GL_DEPTH_TEST);
        for (int l_EyeIndex = 0; l_EyeIndex < ovrEye_Count; l_EyeIndex++) {
            ovrEyeType l_Eye = (*MainRiftDeviceDesc).EyeRenderOrder[l_EyeIndex];
            ovrPosef l_EyePose = ovrHmd_BeginEyeRender((*MainRiftDevice), l_Eye);
            glViewport(MainEyeRenderDesc[l_Eye].Desc.RenderViewport.Pos.x,
                MainEyeRenderDesc[l_Eye].Desc.RenderViewport.Pos.y,
                MainEyeRenderDesc[l_Eye].Desc.RenderViewport.Size.w,
                MainEyeRenderDesc[l_Eye].Desc.RenderViewport.Size.h);
            DirectionOfWhereCameraIsFacing = glm::normalize(CenterOfWhatIsBeingLookedAt - PositionOfEyesOfPerson);
            switch (CurrentCameraMode) {
            case (ModeOfCamera::ORTHOGONAL) :
                break;
                Projection = glm::ortho(CurrentOrthoParameters.LeftPlane, CurrentOrthoParameters.RightPlane,
                    CurrentOrthoParameters.BottomPlane, CurrentOrthoParameters.TopPlane);
            case (ModeOfCamera::PERSPECTIVE) :
            default:
                DirectionOfWhereCameraIsFacing = glm::vec3(l_EyePose.Orientation.x, l_EyePose.Orientation.y, l_EyePose.Orientation.z);
                PositionOfEyesOfPerson += CameraPositionDelta;
                PositionOfEyesOfPerson = PositionOfEyesOfPerson + glm::vec3(MainEyeRenderDesc[l_Eye].ViewAdjust.x, MainEyeRenderDesc[l_Eye].ViewAdjust.y, MainEyeRenderDesc[l_Eye].ViewAdjust.z);
                CenterOfWhatIsBeingLookedAt = PositionOfEyesOfPerson + DirectionOfWhereCameraIsFacing * 1.0f;
                break;
            }
            View = glm::lookAt(PositionOfEyesOfPerson, CenterOfWhatIsBeingLookedAt, DirectionOfUpForPerson);
            Model = glm::mat4(1.0f);
            ModelViewProjectionMatrix = Projection * View * Model;
            ProjectionViewMatrix = Projection * View;
            SetGlobalDirectionalLight();
            if (CurrentShadingMode == SHADING_MODE_SHADED || CurrentShadingMode == SHADING_MODE_FULL_COLOR) {
                glEnable(GL_TEXTURE_2D);
                glUniform1i(GetEnableWireframeID(), 0);
                glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
            }
            else {
                glDisable(GL_TEXTURE_2D);
                glUniform1i(GetEnableWireframeID(), 1);
                glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
            }
            for (GLuint i = 0; i < MainMeshCache.size(); i++) {
                MainMeshCache[i].DrawMe(this);
            }
            glBindVertexArray(0);
            ovrHmd_EndEyeRender((*MainRiftDevice), l_Eye, l_EyePose, &l_EyeTexture[l_Eye].Texture);
        }
        glDisable(GL_CULL_FACE);
        glDisable(GL_DEPTH_TEST);
        ovrHmd_EndFrame((*MainRiftDevice));
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);
        glClearDepth(1);
        glUseProgramObjectARB(0);
    /*
    This is the "MainMeshCache" DrawMe Function.
    */
    DrawMe(GlMaintenance* CurrentOpenGLController) {
    glm::mat4 ModelViewMatrix = CurrentOpenGLController->GetViewMatrix() * ModelMatrix;
    glm::mat3 NormalMatrix = glm::transpose(glm::inverse(glm::mat3(ModelViewMatrix)));
    glm::mat4 ModelViewProjectionMatrix = CurrentOpenGLController->GetProjectionViewMatrix() * ModelMatrix;
    glBindVertexArray(Pointer_VAO);
    glUniformMatrix3fv(CurrentOpenGLController->GetNormalMatrixID(), 1, GL_FALSE,
        glm::value_ptr(NormalMatrix));
    glUniformMatrix4fv(CurrentOpenGLController->GetUniformGlobalPositionID(), 1, GL_FALSE, glm::value_ptr(ModelViewProjectionMatrix));
    for (int i = 0; i < Materials.size(); i++) {
        glUniform4fv(CurrentOpenGLController->GetEmmissiveMeshColorID(), 1, Materials[i].EmissiveColor);
        glUniform4fv(CurrentOpenGLController->GetAmbientMeshColorID(), 1, Materials[i].AmbientColor);
        glUniform4fv(CurrentOpenGLController->GetDiffuseMeshColorID(), 1, Materials[i].DiffuseColor);
        glUniform4fv(CurrentOpenGLController->GetSpecularMeshColorID(), 1, Materials[i].SpecularColor);
        glUniform4fv(CurrentOpenGLController->GetMaterialColorID(), 1, Materials[i].ObjectColor);
        glUniform1f(CurrentOpenGLController->GetMeshShininessID(), Materials[i].Shininess);
        glDrawElements(GL_TRIANGLES, (Materials[i].TriangleCount * 3)
            , GL_UNSIGNED_INT, reinterpret_cast<const GLvoid *>(Materials[i].Offset * sizeof(unsigned int)));
    }
    }

编辑

忘了我的着色器…

    /*
    Vertex Shader
    */
    #version 140
    #extension GL_ARB_explicit_attrib_location : require
    in vec4 vPosition;
    in vec3 vNormal;
    in vec2 vUV;
    out vec3 SurfaceNormal;
    uniform mat4 ModelViewProjectionMatrix;
    uniform mat3 NormalMatrix;
    void main () {
        SurfaceNormal = normalize(NormalMatrix * vNormal);
        gl_Position = ModelViewProjectionMatrix * vPosition;
    }


    /*
    Fragment Shader
    */

    #version 140
    #extension GL_ARB_explicit_attrib_location : require
    //
    // These values vary per Mesh
    //
    uniform vec4    MaterialColor;
    uniform vec4    AmbientMeshColor;
    uniform vec4    EmmissiveMeshColor;
    uniform vec4    DiffuseMeshColor;
    uniform vec4    SpecularMeshColor;
    uniform float   MeshShininess;
    //
    // Wireframe Settings
    //
    uniform int     EnableWireframe;
    uniform vec4    WireframeColor;
    //
    // These values vary depending on settings in running context of the
    // Shader program. 
    //
    uniform int     EnableLighting;
    uniform int     EnableSun;
    uniform vec3    SunDirection;
    uniform vec3    LightHalfVector;
    uniform vec4    SunColor;
    uniform vec4    SunSpotCutoff;
    uniform float   SunlightStrength;
    //
    // Surface normals vary per vertex.
    //
    in vec3 SurfaceNormal;
    //
    // Final output to the Fragment Shader Host Process.
    //
    out vec4 finalColor;
    void main()
    {
        if (EnableWireframe == 1) {
            finalColor = WireframeColor;
        } else {
            //
            // Sunlight enabled. Do the calculations.
            //
            float DiffuseValue = max(0.0, dot(SurfaceNormal, SunDirection));
            float SpecularValue = max(0.0, dot(SurfaceNormal, LightHalfVector));
            if (DiffuseValue == 0.0) {
                SpecularValue = 0.0;
            } else {
                SpecularValue = pow(SpecularValue, MeshShininess);
            }
            vec3 ScatteredLight = AmbientMeshColor.rgb + (SunColor.rgb * DiffuseValue);
            vec3 ReflectedLight = SunColor.rgb * SpecularValue * SunlightStrength;
            vec3 CalculatedColor = min(MaterialColor.rgb * ScatteredLight + ReflectedLight, vec3(1.0));
            finalColor = vec4(CalculatedColor, MaterialColor.a);
        }
    }
glGenBuffers(1, &Vertex_VBO);
                 ^^^^^^^^^^ with you so far....
...
glVertexAttribPointer(Vertex_VBO, Vertex_Stride, GL_FLOAT, GL_FALSE, 0, 0);
                      ^^^^^^^^^^ mmmmnope, type mismatch

VBO id 放在glVertexAttribPointer()的第一个参数中。它只用于属性索引。

你需要(以下其中之一):

  • 在着色器链接glBindAttribLocation()之前绑定属性位置
  • glGetAttribLocation()
  • 查询你的着色器程序(在链接后的)的属性索引
  • 实际上使用 ARB_explicit_attrib_location并使用layout( location = xxx )
  • 在着色器中指定属性位置

一旦你弄清楚或决定了你的属性索引是什么,你可以把它们传递给glVertexAttribPointer()