openvr icon indicating copy to clipboard operation
openvr copied to clipboard

"Next up" or "Waiting" with my windows title appears on my headset (OpenGL + OpenVR)...

Open mileticveljko opened this issue 2 years ago • 3 comments

Hello guys, Tried so hard to debug this -> Really can't find error... I am posting the simplest code possible that get same issue. My VR headset is Oculus Rift S.

Click to expand
#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include "Shader.h"

#include "glm.hpp"
#include "gtc/matrix_transform.hpp"

#include "openvr.h"

#include <iostream>

// Declare OpenVR system pointer
// Initialize OpenVR
vr::IVRSystem* pVRSystem = vr::VR_Init(nullptr, vr::VRApplication_Scene);

// Get HMD handle
vr::TrackedDeviceIndex_t hmdIndex = pVRSystem->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_Invalid);

// Set up compositor
vr::IVRCompositor* vrCompositor = vr::VRCompositor();

// Initialize OpenVR
bool InitOpenVR()
{
    vr::EVRInitError eError = vr::VRInitError_None;

    pVRSystem = vr::VR_Init(&eError, vr::VRApplication_Scene);

    if (eError != vr::VRInitError_None)
    {
        printf("OpenVR initialization failed: %s\n", vr::VR_GetVRInitErrorAsEnglishDescription(eError));
        return false;
    }

    return true;
}

// Render loop
void RenderLoop()
{
    // Wait for poses
    vr::TrackedDevicePose_t trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
    vr::VRCompositor()->WaitGetPoses(trackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0);

    // Get projection matrix and eye-to-head transform for each eye
    vr::HmdMatrix44_t matProjectionLeft = pVRSystem->GetProjectionMatrix(vr::Eye_Left, 0.1f, 100.f);
    vr::HmdMatrix44_t matProjectionRight = pVRSystem->GetProjectionMatrix(vr::Eye_Right, 0.1f, 100.f);
    vr::HmdMatrix34_t matEyeLeft = pVRSystem->GetEyeToHeadTransform(vr::Eye_Left);
    vr::HmdMatrix34_t matEyeRight = pVRSystem->GetEyeToHeadTransform(vr::Eye_Right);

    // Set up OpenGL state for rendering
    glClearColor(0.2f, 0.5f, 0.3f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Render textured cube from correct perspective for each eye
    for (int eye = 0; eye < vr::k_unMaxTrackedDeviceCount; ++eye) {
        vr::HmdMatrix34_t matEye = (eye == vr::Eye_Left) ? matEyeLeft : matEyeRight;
        vr::HmdMatrix44_t projection = (eye == vr::Eye_Left) ? matProjectionLeft : matProjectionRight;

        // Define the vertices of the triangle
        GLfloat vertices[] = {
            -0.5f, -0.5f, 0.0f,
             0.5f, -0.5f, 0.0f,
             0.0f,  0.5f, 0.0f
        };

        // Create the vertex buffer object and vertex array object
        GLuint VBO, VAO;
        glGenBuffers(1, &VBO);
        glGenVertexArrays(1, &VAO);

        // Bind the VAO and VBO
        glBindVertexArray(VAO);
        glBindBuffer(GL_ARRAY_BUFFER, VBO);

        // Copy the vertices to the buffer
        glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

        // Set up the vertex attributes
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);
        glEnableVertexAttribArray(0);

        // Unbind the VAO and VBO
        glBindBuffer(GL_ARRAY_BUFFER, 0);
        glBindVertexArray(0);

        // Set up the shader program
        Shader shader("vertex_shader.glsl", "fragment_shader.glsl");

        // Set the projection and view matrices
        glm::mat4 view = glm::mat4(glm::vec4(matEye.m[0][0], matEye.m[1][0], matEye.m[2][0], 0.0f),
            glm::vec4(matEye.m[0][1], matEye.m[1][1], matEye.m[2][1], 0.0f),
            glm::vec4(matEye.m[0][2], matEye.m[1][2], matEye.m[2][2], 0.0f),
            glm::vec4(matEye.m[0][3], matEye.m[1][3], matEye.m[2][3], 1.0f));
        
        glm::mat4 glmMat(
            projection.m[0][0], projection.m[1][0], projection.m[2][0], projection.m[3][0],
            projection.m[0][1], projection.m[1][1], projection.m[2][1], projection.m[3][1],
            projection.m[0][2], projection.m[1][2], projection.m[2][2], projection.m[3][2],
            projection.m[0][3], projection.m[1][3], projection.m[2][3], projection.m[3][3]
        );
        glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(0, 0, -1)); 
        glm::mat4 mvp = glmMat * view * model;

        // Use the shader program and set the model-view-projection matrix
        shader.use();
        shader.setMat4("mvp", mvp);

        // Bind the VAO and draw the triangle
        glBindVertexArray(VAO);
        glDrawArrays(GL_TRIANGLES, 0, 3);
        glBindVertexArray(0);

        vr::VRCompositor()->Submit(vr::Eye_Left, nullptr);
        vr::VRCompositor()->Submit(vr::Eye_Right, nullptr);
    }
}

// Cleanup OpenVR
void CleanupOpenVR()
{
    vr::VR_Shutdown();
}

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

int main()
{
    // glfw: initialize and configure
    // ------------------------------
    glfwInit();
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
    glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
#endif

    // glfw window creation
    // --------------------
    GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "Okruzenje", NULL, NULL);
    if (window == NULL)
    {
        std::cout << "Failed to create GLFW window" << std::endl;
        glfwTerminate();
        return -1;
    }
    glfwMakeContextCurrent(window);

    // glad: load all OpenGL function pointers
    // ---------------------------------------
    if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))
    {
        std::cout << "Failed to initialize GLAD" << std::endl;
        return -1;
    }

    if (!InitOpenVR())
    {
        return -1;
    }

    // configure global opengl state
    // -----------------------------
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    // render loop
    // -----------
    while (!glfwWindowShouldClose(window))
    {
        glfwPollEvents();

        // render
        // ------
        RenderLoop();

        glfwSwapBuffers(window);
    }
    CleanupOpenVR();
    glfwTerminate();
    return 0;
}

Shader.h really worked on my other project, and shaders are written correctly - Window shows up on screen correctly but on VR set shows up the issue I mentioned.

Thank You!

mileticveljko avatar Mar 17 '23 19:03 mileticveljko

The Submit() calls aren't including any textures.

Rectus avatar Mar 18 '23 15:03 Rectus

Just that?

Thank you

mileticveljko avatar Mar 19 '23 14:03 mileticveljko

That's the first thing that stuck me in the eyes at least. Submitting the frames is what causes SteamVR to switch from rendering the title card to start rendering the application.

The documentation in the header says that you might want to call glFlush() as well. https://github.com/ValveSoftware/openvr/blob/master/headers/openvr.h#L3361

Rectus avatar Mar 19 '23 15:03 Rectus