gpt4 book ai didi

c++ - 如何在 C++ 中使用 OSVR?

转载 作者:搜寻专家 更新时间:2023-10-31 02:10:34 28 4
gpt4 key购买 nike

我想使用来自 OSVR 的插件,但我不知道它到底是如何工作的。

在 OpenVR 中,我的每只眼睛都有一个帧缓冲区,当我在该缓冲区上写一些东西时,我会在眼镜中看到它们,我正在使用 HTC Vive。

但现在我不知道那些缓冲区在哪里以及如何更改 VR 眼睛内容,并且我正确安装了 OSVR 服务器和 OSVR Vive 插件,但即使是这个简单的示例也无法正常工作,我看不到VR 中的任何内容:

#include <osvr/ClientKit/ClientKit.h>
#include <osvr/ClientKit/Display.h>
#include "SDL2Helpers.h"
#include "OpenGLCube.h"

#include <SDL.h>
#include <SDL_opengl.h>

#include <iostream>

static auto const WIDTH = 1920;
static auto const HEIGHT = 1080;

// Forward declarations of rendering functions defined below.
void render(osvr::clientkit::DisplayConfig &disp);
void renderScene();

int main(int argc, char *argv[]) {
namespace SDL = osvr::SDL2;

// Open SDL
SDL::Lib lib;

// Use OpenGL 2.1
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);

// Create a window
auto window = SDL::createWindow("OSVR", SDL_WINDOWPOS_UNDEFINED,
SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT,
SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN);
if (!window) {
std::cerr << "Could not create window: " << SDL_GetError() << std::endl;
return -1;
}

// Create an OpenGL context and make it current.
SDL::GLContext glctx(window.get());

// Turn on V-SYNC
SDL_GL_SetSwapInterval(1);

// Start OSVR and get OSVR display config
osvr::clientkit::ClientContext ctx("com.osvr.example.SDLOpenGL");
osvr::clientkit::DisplayConfig display(ctx);
if (!display.valid()) {
std::cerr << "\nCould not get display config (server probably not "
"running or not behaving), exiting."
<< std::endl;
return -1;
}

std::cout << "Waiting for the display to fully start up, including "
"receiving initial pose update..."
<< std::endl;
while (!display.checkStartup()) {
ctx.update();
}
std::cout << "OK, display startup status is good!" << std::endl;

// Event handler
SDL_Event e;
#ifndef __ANDROID__ // Don't want to pop up the on-screen keyboard
SDL::TextInput textinput;
#endif
bool quit = false;
while (!quit) {
// Handle all queued events
while (SDL_PollEvent(&e)) {
switch (e.type) {
case SDL_QUIT:
// Handle some system-wide quit event
quit = true;
break;
case SDL_KEYDOWN:
if (SDL_SCANCODE_ESCAPE == e.key.keysym.scancode) {
// Handle pressing ESC
quit = true;
}
break;
}
if (e.type == SDL_QUIT) {
quit = true;
}
}

// Update OSVR
ctx.update();

// Render
render(display);

// Swap buffers
SDL_GL_SwapWindow(window.get());
}

return 0;
}

/// @brief A simple dummy "draw" function - note that drawing occurs in "room
/// space" by default. (that is, in this example, the modelview matrix when this
/// function is called is initialized such that it transforms from world space
/// to view space)
void renderScene() { draw_cube(1.0); }

/// @brief The "wrapper" for rendering to a device described by OSVR.
///
/// This function will set up viewport, initialize view and projection matrices
/// to current values, then call `renderScene()` as needed (e.g. once for each
/// eye, for a simple HMD.)
void render(osvr::clientkit::DisplayConfig &disp) {

// Clear the screen to black and clear depth
glClearColor(0, 0, 0, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/// For each viewer, eye combination...
disp.forEachEye([](osvr::clientkit::Eye eye) {

/// Try retrieving the view matrix (based on eye pose) from OSVR
double viewMat[OSVR_MATRIX_SIZE];
eye.getViewMatrix(OSVR_MATRIX_COLMAJOR | OSVR_MATRIX_COLVECTORS,
viewMat);
/// Initialize the ModelView transform with the view matrix we
/// received
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glMultMatrixd(viewMat);

/// For each display surface seen by the given eye of the given
/// viewer...
eye.forEachSurface([](osvr::clientkit::Surface surface) {
auto viewport = surface.getRelativeViewport();
glViewport(static_cast<GLint>(viewport.left),
static_cast<GLint>(viewport.bottom),
static_cast<GLsizei>(viewport.width),
static_cast<GLsizei>(viewport.height));

/// Set the OpenGL projection matrix based on the one we
/// computed.
double zNear = 0.1;
double zFar = 100;
double projMat[OSVR_MATRIX_SIZE];
surface.getProjectionMatrix(
zNear, zFar, OSVR_MATRIX_COLMAJOR | OSVR_MATRIX_COLVECTORS |
OSVR_MATRIX_SIGNEDZ | OSVR_MATRIX_RHINPUT,
projMat);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMultMatrixd(projMat);

/// Set the matrix mode to ModelView, so render code doesn't
/// mess with the projection matrix on accident.
glMatrixMode(GL_MODELVIEW);

/// Call out to render our scene.
renderScene();
});
});

/// Successfully completed a frame render.
}

有人知道它是如何工作的吗?

最佳答案

不使用显示配置 API,而是使用 osvrRenderManager 获取渲染信息并将帧呈现给 HMD。显示配置 API 是较低级别的 API,不处理 Vive 上扩展模式渲染或直接模式渲染的窗口放置,或基于渲染目标比例因子调整投影等事情。这通常由 RenderManager API 处理。

https://github.com/sensics/osvr-rendermanager

关于c++ - 如何在 C++ 中使用 OSVR?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45026305/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com