ValveSoftware / openvr

OpenVR SDK
http://steamvr.com
BSD 3-Clause "New" or "Revised" License
6.12k stars 1.28k forks source link

VR Window created but not shown in headset #1814

Closed Outssiss closed 9 months ago

Outssiss commented 9 months ago

I have this code, whic creates a VR scene using OpenGL:

#include "vrApp.h"

using namespace glm;

GLuint CGLRenderModel::m_rendermodelMatrixLocation;
GLuint CGLRenderModel::shader_rendermodel;

void ThreadSleep(unsigned long milliSeconds) 
{
#if defined(_WIN32)
    ::Sleep(milliSeconds);
#elif defined(POSIX)
    usleep(nMilliseconds * 1000);
#endif
}

CGLRenderModel::CGLRenderModel(const std::string& sRenderModelName)
    : m_sModelName(sRenderModelName)
{
    m_glIndexBuffer = 0;
    m_glVertArray = 0;
    m_glVertBuffer = 0;
    m_glTexture = 0;
}

bool openvr::init()
{
    glfwInit();
    width = 1400; height = 900;
    window = glfwCreateWindow(width, height, "OpenGL", nullptr, nullptr);
    glfwMakeContextCurrent(window);

    glewExperimental = GL_TRUE;
    GLenum nGlewError = glewInit();

    if (nGlewError != GLEW_OK) {
        printf("%s - Error initializing GLEW! %s\n", __FUNCTION__, glewGetErrorString(nGlewError));
        return false;
    }
    glGetError(); // to clear the error caused deep in GLEW. Mirar el tutorial del notas de OPENGL para entender esto mejor.

    textureLoader::Init();

    vr::EVRInitError eError = vr::VRInitError_None;
    m_pHMD = vr::VR_Init(&eError, vr::VRApplication_Scene);
    if (eError != vr::VRInitError_None)
    {
        m_pHMD = NULL;
        char buf[1024];
        sprintf_s(buf, sizeof(buf), "Unable to init VR runtime: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError));
        return false;
    }

    m_fFarClip = 30.0f;
    m_fNearClip = 0.1f;

    m_model = mat4(1.0f);

    //initGL
    createShader(); //Definir
    setupScene(); //Definir
    setupCameras(); //Definir
    setupStereoRenderTargets(); //Definir

    //init Compositor
    vr::EVRInitError peError = vr::VRInitError_None;
    if (!vr::VRCompositor())
    {
        printf("Compositor initialization failed. See log file for details\n");
        return false;
    }

    return true;
}

void openvr::createShader()
{
    Shader lshader_scene("res/shaders/vr_scene.vert", "res/shaders/vr_scene.frag");
    Shader lshader_quad("res/shaders/fbovertex.vert", "res/shaders/fbofragment.frag");
    Shader lshader_skybox("res/shaders/skybox.vert", "res/shaders/skybox.frag");
    Shader lshader_rendermodel("res/shaders/rendermodel.vert", "res/shaders/rendermodel.frag");

    shader_scene = lshader_scene.ID;
    shader_quad = lshader_quad.ID;
    shader_skybox = lshader_skybox.ID;
    CGLRenderModel::shader_rendermodel = lshader_rendermodel.ID;

    m_nSceneMatrixLocation = glGetUniformLocation(shader_scene, "matrix");
    m_assimpMatrixLocation = glGetUniformLocation(shader_assimp, "matrix");
    m_nSkyboxMatrixLocation = glGetUniformLocation(shader_skybox, "matrix");
    CGLRenderModel::m_rendermodelMatrixLocation = glGetUniformLocation(CGLRenderModel::shader_rendermodel, "matrix");
    lshader_scene.use();
}

void openvr::setupSkybox() {
    GLfloat skyboxVertices[] = {
        // positions          
        -1.0f,  1.0f, -1.0f,
        -1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f, -1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,

        -1.0f, -1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f, -1.0f,  1.0f,
        -1.0f, -1.0f,  1.0f,

        -1.0f,  1.0f, -1.0f,
        1.0f,  1.0f, -1.0f,
        1.0f,  1.0f,  1.0f,
        1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f,  1.0f,
        -1.0f,  1.0f, -1.0f,

        -1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f, -1.0f,
        1.0f, -1.0f, -1.0f,
        -1.0f, -1.0f,  1.0f,
        1.0f, -1.0f,  1.0f
    };

    //skybox texture
    std::vector<std::string> faces
    {
      "res/textures/skybox/right.jpg",
      "res/textures/skybox/left.jpg",
      "res/textures/skybox/top.jpg",
      "res/textures/skybox/bottom.jpg",
      "res/textures/skybox/front.jpg",
      "res/textures/skybox/back.jpg"
    };
    texture_skybox = textureLoader::loadCubemap(faces);

    glGenVertexArrays(1, &vao_skybox);
    glBindVertexArray(vao_skybox);

    //vertex Attributes
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);

    //load layout location of position
    GLint posAttrib = glGetAttribLocation(shader_skybox, "position");
    glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, 0);
    glEnableVertexAttribArray(posAttrib);

    GLint texpos = glGetAttribLocation(shader_skybox, "skybox");
    glUniform1i(texpos, 0);

}

void openvr::setupScene()
{
    GLfloat vertices[] = {
        //  X       Y       Z     R     G     B     U     V
            -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
             0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
             0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
             0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
            -0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,

            -0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
             0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
             0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
             0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
            -0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
            -0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,

            -0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
            -0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
            -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
            -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
            -0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
            -0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,

             0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
             0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
             0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
             0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
             0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
             0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,

            -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
             0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
             0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
             0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
            -0.5f, -0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
            -0.5f, -0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,

            -0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f,
             0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f,
             0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
             0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 1.0f, 0.0f,
            -0.5f,  0.5f,  0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f,
            -0.5f,  0.5f, -0.5f, 1.0f, 1.0f, 1.0f, 0.0f, 1.0f
    };

    glGenVertexArrays(1, &vao_scene);
    glBindVertexArray(vao_scene);

    //Texture
    texture_jessica = textureLoader::loadImage("res/textures/img_test.png");

    //Vertex atrb
    GLuint vbo;
    glGenBuffers(1, &vbo);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_DYNAMIC_DRAW);

    //load layout location of position
    GLint posAttrib = glGetAttribLocation(shader_scene, "position");
    glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), 0);
    glEnableVertexAttribArray(posAttrib);

    //color
    GLint colAttrib = glGetAttribLocation(shader_scene, "color");
    glVertexAttribPointer(colAttrib, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)(sizeof(GL_FLOAT) * 3));
    glEnableVertexAttribArray(colAttrib);

    //texcoords
    GLint texAttrib = glGetAttribLocation(shader_scene, "texcoord");
    glVertexAttribPointer(texAttrib, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GL_FLOAT), (void*)(sizeof(GL_FLOAT) * 6));
    glEnableVertexAttribArray(texAttrib);

    //sampler uniform
    GLint texpos = glGetAttribLocation(shader_scene, "tex");
    glUniform1i(texpos, 0);

    glBindVertexArray(0);

    //companion window

    glUseProgram(shader_quad);
    GLfloat screenQuadVertices[] =
    {// x       y   r   g   b
      -1.0, -1.0, 1.0, 0.0, 0.0, 0.0, 0.0,
      1.0, -1.0, 1.0, 1.0, 1.0, 1.0, 0.0,
      1.0,  1.0, 0.0, 1.0, 1.0, 1.0, 1.0,
      -1.0,  1.0, 1.0, 1.0, 1.0, 0.0, 1.0
    };

    glGenVertexArrays(1, &vao_quad);
    glBindVertexArray(vao_quad);

    //vertex Attributes
    GLuint vbo2;
    glGenBuffers(1, &vbo2);
    glBindBuffer(GL_ARRAY_BUFFER, vbo2);
    glBufferData(GL_ARRAY_BUFFER, sizeof(screenQuadVertices), screenQuadVertices, GL_DYNAMIC_DRAW);

    //load layout location of position
    GLint posAttrib2 = glGetAttribLocation(shader_quad, "position");
    glVertexAttribPointer(posAttrib2, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GL_FLOAT), 0);
    glEnableVertexAttribArray(posAttrib2);

    //color
    GLint colAttrib2 = glGetAttribLocation(shader_quad, "color");
    glVertexAttribPointer(colAttrib2, 3, GL_FLOAT, GL_FALSE, 7 * sizeof(GL_FLOAT), (void*)(sizeof(GL_FLOAT) * 2));
    glEnableVertexAttribArray(colAttrib2);

    //texcoords
    GLint texAttrib2 = glGetAttribLocation(shader_quad, "texcoord");
    glVertexAttribPointer(texAttrib2, 2, GL_FLOAT, GL_FALSE, 7 * sizeof(GL_FLOAT), (void*)(sizeof(GL_FLOAT) * 5));
    glEnableVertexAttribArray(texAttrib2);

    //sampler uniform
    GLint texpos2 = glGetAttribLocation(shader_quad, "tex");
    glUniform1i(texpos2, 0);

    glBindVertexArray(0);

    setupSkybox();
}

void openvr::setupCameras()
{
    m_mat4ProjectionLeft = GetHMDMatrixProjectionEye(vr::Eye_Left);
    m_mat4ProjectionRight = GetHMDMatrixProjectionEye(vr::Eye_Right);

    m_mat4eyePosLeft = GetHMDMatrixPoseEye(vr::Eye_Left);
    m_mat4eyePosRight = GetHMDMatrixPoseEye(vr::Eye_Right);

    m_mat4HMDPose = mat4(1.0f);
}

mat4 openvr::GetHMDMatrixProjectionEye(vr::Hmd_Eye nEye) {

    vr::HmdMatrix44_t mat = m_pHMD->GetProjectionMatrix(nEye, m_fNearClip, m_fFarClip);

    //return a glm mat4
    return mat4(
        mat.m[0][0], mat.m[1][0], mat.m[2][0], mat.m[3][0],
        mat.m[0][1], mat.m[1][1], mat.m[2][1], mat.m[3][1],
        mat.m[0][2], mat.m[1][2], mat.m[2][2], mat.m[3][2],
        mat.m[0][3], mat.m[1][3], mat.m[2][3], mat.m[3][3]
    );

}

mat4 openvr::GetHMDMatrixPoseEye(vr::Hmd_Eye nEye)
{

    vr::HmdMatrix34_t matEyeRight = m_pHMD->GetEyeToHeadTransform(nEye);
    mat4 matrixObj(
        matEyeRight.m[0][0], matEyeRight.m[1][0], matEyeRight.m[2][0], 0.0,
        matEyeRight.m[0][1], matEyeRight.m[1][1], matEyeRight.m[2][1], 0.0,
        matEyeRight.m[0][2], matEyeRight.m[1][2], matEyeRight.m[2][2], 0.0,
        matEyeRight.m[0][3], matEyeRight.m[1][3], matEyeRight.m[2][3], 1.0f
    );

    return inverse(matrixObj);
}

void openvr::setupStereoRenderTargets()
{
    m_pHMD->GetRecommendedRenderTargetSize(&m_nRenderWidth, &m_nRenderHeight);

    createFrameBuffer(m_nRenderWidth, m_nRenderHeight, leftEyeDesc);
    createFrameBuffer(m_nRenderWidth, m_nRenderHeight, rightEyeDesc);
}

void openvr::createFrameBuffer(int nWidth, int nHeight, FramebufferDesc& framebufferDesc)
{
    glGenFramebuffers(1, &framebufferDesc.m_nRenderFramebufferId);
    glBindFramebuffer(GL_FRAMEBUFFER, framebufferDesc.m_nRenderFramebufferId);

    glGenRenderbuffers(1, &framebufferDesc.m_nDepthBufferId);
    glBindRenderbuffer(GL_RENDERBUFFER, framebufferDesc.m_nDepthBufferId);
    glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, nWidth, nHeight);
    glBindRenderbuffer(GL_RENDERBUFFER, 0);

    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, framebufferDesc.m_nDepthBufferId);

    glGenTextures(1, &framebufferDesc.m_nRenderTextureId);
    glBindTexture(GL_TEXTURE_2D, framebufferDesc.m_nRenderTextureId);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, nWidth, nHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, framebufferDesc.m_nRenderTextureId, 0);

    glBindTexture(GL_TEXTURE_2D, 0);

    // check FBO status
    if (glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) {
        std::cout << "Framebuffer creation successful." << std::endl;
    }
    else {
        std::cout << "Framebuffer creation FAILED." << std::endl;
    }

    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void openvr::runMainLoop()
{
    while (!glfwWindowShouldClose(window))
    {
        updateHMDMatrixPose();

        renderStereoTargets();

        drawScreenQuad();

        vr::Texture_t leftEyeTexture = { (void*)(uintptr_t)leftEyeDesc.m_nRenderTextureId, vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
        vr::VRCompositor()->Submit(vr::Eye_Left, &leftEyeTexture);
        vr::Texture_t rightEyeTexture = { (void*)(uintptr_t)rightEyeDesc.m_nRenderTextureId, vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
        vr::VRCompositor()->Submit(vr::Eye_Right, &rightEyeTexture);

        glfwSwapBuffers(window);
        glfwPollEvents();
    }
}

void openvr::drawScreenQuad()
{
    glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT);

    glViewport(0, 0, width / 2, height);

    glBindTexture(GL_TEXTURE_2D, rightEyeDesc.m_nRenderTextureId);
    glUseProgram(shader_quad);
    glBindVertexArray(vao_quad);
    glDrawArrays(GL_POLYGON, 0, 4);

    glViewport(width / 2, 0, width, height);

    glBindTexture(GL_TEXTURE_2D, leftEyeDesc.m_nRenderTextureId);
    glUseProgram(shader_quad);
    glBindVertexArray(vao_quad);
    glDrawArrays(GL_POLYGON, 0, 4);

    glBindVertexArray(0);
}

void openvr::renderStereoTargets()
{
    glBindFramebuffer(GL_FRAMEBUFFER, leftEyeDesc.m_nRenderFramebufferId);
    glViewport(0, 0, m_nRenderWidth, m_nRenderHeight);
    renderScene(vr::Eye_Left);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);

    glBindFramebuffer(GL_FRAMEBUFFER, rightEyeDesc.m_nRenderFramebufferId);
    glViewport(0, 0, m_nRenderWidth, m_nRenderHeight);
    renderScene(vr::Eye_Right);
    glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void openvr::renderScene(vr::Hmd_Eye nEye)
{
    glClearColor(0.3f, 0.2f, 0.5f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    //skybox
    glDepthMask(GL_FALSE);
    glUseProgram(shader_skybox);
    glUniformMatrix4fv(m_nSkyboxMatrixLocation, 1, GL_FALSE, value_ptr(getSkyboxMatrix(nEye)));
    glBindVertexArray(vao_skybox);
    glBindTexture(GL_TEXTURE_CUBE_MAP, texture_skybox);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glDepthMask(GL_TRUE);

    //cube

    glEnable(GL_DEPTH_TEST);
    glUseProgram(shader_scene);

    m_model = rotate(m_model, radians(0.1f), vec3(1.0, 0.0, 0.0));

    glUniformMatrix4fv(m_nSceneMatrixLocation, 1, GL_FALSE, value_ptr(getCurrentViewProjectionMatrix(nEye) * m_model));
    glBindVertexArray(vao_scene);
    glBindTexture(GL_TEXTURE_2D, texture_jessica);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    glDisable(GL_DEPTH_TEST);
}

void openvr::updateHMDMatrixPose()
{
    vr::VRCompositor()->WaitGetPoses(m_rTrackedDevicePose, vr::k_unMaxTrackedDeviceCount, NULL, 0);

    m_rmat4DevicePose[vr::k_unTrackedDeviceIndex_Hmd] = convertSteamVRMatrixToMat4(m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking);

    if (m_rTrackedDevicePose[vr::k_unTrackedDeviceIndex_Hmd].bPoseIsValid)
    {
        m_mat4HMDPose = m_rmat4DevicePose[vr::k_unTrackedDeviceIndex_Hmd];
        m_mat4HMDPose = inverse(m_mat4HMDPose);
    }
}

mat4 openvr::convertSteamVRMatrixToMat4(const vr::HmdMatrix34_t& matPose) {
    mat4 matrixObj(
        matPose.m[0][0], matPose.m[1][0], matPose.m[2][0], 0.0,
        matPose.m[0][1], matPose.m[1][1], matPose.m[2][1], 0.0,
        matPose.m[0][2], matPose.m[1][2], matPose.m[2][2], 0.0,
        matPose.m[0][3], matPose.m[1][3], matPose.m[2][3], 1.0f
    );
    return matrixObj;
}

mat4 openvr::getSkyboxMatrix(vr::Hmd_Eye nEye)
{
    mat4 matMVP;
    if (nEye == vr::Eye_Left)
    {
        //remove translation from pose
        mat4 pose = mat4(mat3(m_mat4HMDPose));
        matMVP = m_mat4ProjectionLeft * m_mat4eyePosLeft * pose;
    }
    else if (nEye == vr::Eye_Right)
    {
        mat4 pose = mat4(mat3(m_mat4HMDPose));
        matMVP = m_mat4ProjectionRight * m_mat4eyePosRight * pose;
    }

    return matMVP;
}

mat4 openvr::getCurrentViewProjectionMatrix(vr::Hmd_Eye nEye)
{
    mat4 matMVP;
    if (nEye == vr::Eye_Left)
    {
        matMVP = m_mat4ProjectionLeft * m_mat4eyePosLeft * m_mat4HMDPose;
    }
    else if (nEye == vr::Eye_Right)
    {
        matMVP = m_mat4ProjectionRight * m_mat4eyePosRight * m_mat4HMDPose;
    }

    return matMVP;
}

int main(int argc, char* argv[])
{
    openvr* op = new openvr();

    op->init();

    op->runMainLoop();

    return 0;

}

This is the include file:

#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <openvr.h>
#include <glm.hpp>
#include <gtc/matrix_transform.hpp>
#include <gtc/type_ptr.hpp>
#include <gtc/matrix_inverse.hpp>
#include "textureLoader.h"
#include "shader.h"

class CGLRenderModel
{
public:
    CGLRenderModel(const std::string& sRenderModelName);
    bool BInit(const vr::RenderModel_t& vrModel, const vr::RenderModel_TextureMap_t& vrDiffuseTexture);
    void DrawCube(GLuint texture);
    const std::string& GetName() const { return m_sModelName; }

    static GLuint shader_rendermodel;
    static GLuint m_rendermodelMatrixLocation;

private:
    GLuint m_glVertBuffer;
    GLuint m_glIndexBuffer;
    GLuint m_glVertArray;
    GLuint m_glCubeArray;
    GLuint m_glTexture;
    GLsizei m_unVertexCount;
    std::string m_sModelName;
};

class openvr
{
    GLFWwindow* window;
    int width;
    int height;
    vr::IVRSystem* m_pHMD;

    struct FramebufferDesc
    {
        GLuint m_nDepthBufferId;
        GLuint m_nRenderTextureId;
        GLuint m_nRenderFramebufferId;
    };

    FramebufferDesc leftEyeDesc;
    FramebufferDesc rightEyeDesc;

    uint32_t m_nRenderWidth;
    uint32_t m_nRenderHeight;

    glm::mat4 m_model;

    glm::mat4 m_mat4HMDPose;
    glm::mat4 m_mat4eyePosLeft;
    glm::mat4 m_mat4eyePosRight;

    glm::mat4 m_mat4ProjectionCenter;
    glm::mat4 m_mat4ProjectionLeft;
    glm::mat4 m_mat4ProjectionRight;

    float m_fNearClip;
    float m_fFarClip;

    //Estos shaders tendre que borrarlos por el mio
    GLuint shader_scene;
    GLuint shader_quad;
    GLuint shader_skybox;
    GLuint shader_assimp;

    GLuint vao_scene;
    GLuint vao_quad;
    GLuint vao_skybox;
    GLuint texture_jessica;
    GLuint texture_skybox;

    GLuint m_nSceneMatrixLocation;
    GLuint m_nSceneModelLocation;
    GLuint m_nSkyboxMatrixLocation;
    GLuint m_assimpMatrixLocation;

    vr::TrackedDevicePose_t m_rTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
    glm::mat4 m_rmat4DevicePose[vr::k_unMaxTrackedDeviceCount];

public:
    bool init();
    void runMainLoop();
    void createShader();
    void setupScene();
    void setupSkybox();
    void setupCameras();
    void setupStereoRenderTargets();
    void renderStereoTargets();

    void renderScene(vr::Hmd_Eye nEye);

    void drawScreenQuad();

    void updateHMDMatrixPose();
    glm::mat4 GetHMDMatrixProjectionEye(vr::Hmd_Eye nEye);
    glm::mat4 GetHMDMatrixPoseEye(vr::Hmd_Eye nEye);

    glm::mat4 getCurrentViewProjectionMatrix(vr::Hmd_Eye nEye);
    glm::mat4 getSkyboxMatrix(vr::Hmd_Eye nEye);

    glm::mat4 convertSteamVRMatrixToMat4(const vr::HmdMatrix34_t& matPose);

    void createFrameBuffer(int nWidth, int nHeight, FramebufferDesc& framebufferDesc);
};

A window is created in the PC screen and the headset movement is followed correctly.

Capture

But on the headset nothing is seen:

Casdasdapture

Outssiss commented 9 months ago

I was able to determine that the Submit was throwing a Compositor error 105, which is VRCompositorError_TextureUsesUnsupportedFormat. The headset being used is an HTC Vive Pro

Rectus commented 9 months ago

Try using an RGBA texture instead of an RGB one.

I'm guessing this is due to SteamVR using DirectX 11 internally, which doesn't support 24 bit texture formats. https://learn.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format

Outssiss commented 9 months ago

Try using an RGBA texture instead of an RGB one.

I'm guessing this is due to SteamVR using DirectX 11 internally, which doesn't support 24 bit texture formats. https://learn.microsoft.com/en-us/windows/win32/api/dxgiformat/ne-dxgiformat-dxgi_format

It was exactly that. Now the scene renders in the headset. Thanks!