b.1:
主要是增加了SetupRC这个初始化函数,读取天空盒六面图片。
#include
#include
#include
#if defined( OSX )
#include
#include
#include
// Apple's version of glut.h #undef's APIENTRY, redefine it
#define APIENTRY
#else
#include
#endif
#include
#include
#include
#include
#include "shared/lodepng.h"
#include "shared/Matrices.h"
#include "shared/pathtools.h"
#if defined(POSIX)
#include "unistd.h"
#endif
#ifndef _WIN32
#define APIENTRY
#endif
#ifndef _countof
#define _countof(x) (sizeof(x)/sizeof((x)[0]))
#endif
void ThreadSleep(unsigned long nMilliseconds)
{
#if defined(_WIN32)
::Sleep(nMilliseconds);
#elif defined(POSIX)
usleep(nMilliseconds * 1000);
#endif
}
#include // OpenGL toolkit
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace cv;
GLFrame viewFrame;
GLFrustum viewFrustum;
GLTriangleBatch sphereBatch;
GLBatch cubeBatch;
GLMatrixStack modelViewMatrix;
GLMatrixStack projectionMatrix;
GLGeometryTransform transformPipeline;
GLuint cubeTexture;
GLint reflectionShader;
GLint skyBoxShader;
GLint locMVPReflect, locMVReflect, locNormalReflect, locInvertedCamera;
GLint locMVPSkyBox;
// Six sides of a cube map
char *szCubeFaces[6] = { "pos_x.tga", "neg_x.tga", "pos_y.tga", "neg_y.tga", "pos_z.tga", "neg_z.tga" };
GLenum cube[6] = { GL_TEXTURE_CUBE_MAP_POSITIVE_X,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z };
void SetupRC()
{
unsigned char *pBytes;
//GLbyte *pBytes;
GLint iWidth, iHeight, iComponents;
GLenum eFormat;
int i;
int R;
glGenTextures(1, &cubeTexture);//创建
glBindTexture(GL_TEXTURE_CUBE_MAP, cubeTexture);//绑定纹理ID到一个纹理单元
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);//设置纹理单元的过滤方式、插值方式等
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);//
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);//
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);//
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);//
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
Mat img[6];
img[0] = imread("C:\\Proj\\openvr-master\\samples\\hellovr_opengl\\ll0.jpg", CV_LOAD_IMAGE_COLOR);
img[1] = imread("C:\\Proj\\openvr-master\\samples\\hellovr_opengl\\ll1.jpg", CV_LOAD_IMAGE_COLOR);
img[2] = imread("C:\\Proj\\openvr-master\\samples\\hellovr_opengl\\ll2.jpg", CV_LOAD_IMAGE_COLOR);
img[3] = imread("C:\\Proj\\openvr-master\\samples\\hellovr_opengl\\ll3.jpg", CV_LOAD_IMAGE_COLOR);
img[4] = imread("C:\\Proj\\openvr-master\\samples\\hellovr_opengl\\ll4.jpg", CV_LOAD_IMAGE_COLOR);
img[5] = imread("C:\\Proj\\openvr-master\\samples\\hellovr_opengl\\ll5.jpg", CV_LOAD_IMAGE_COLOR);
R = img[0].rows;
pBytes = (unsigned char*)malloc(R * R * 3 * sizeof(unsigned char));
// Load Cube Map images
for (i = 0; i < 6; i++)
{
// Load this texture map
memcpy(pBytes, (char *)(img[i].data), R * R * 3 * sizeof(unsigned char));//拷贝 (目的 起始 字节数)
//pBytes = gltReadTGABits(szCubeFaces[i], &iWidth, &iHeight, &iComponents, &eFormat);
glTexImage2D(cube[i], 0, GL_RGB, R, R, 0, GL_BGR_EXT, GL_UNSIGNED_BYTE, pBytes);//format不要动 将内存中的数据拷贝到OpenGL纹理单元中
//glTexImage2D(cube[i], 0, iComponents, iWidth, iHeight, 0, eFormat, GL_UNSIGNED_BYTE, pBytes);
}
glGenerateMipmap(GL_TEXTURE_CUBE_MAP);
gltMakeCube(cubeBatch, 16.0f);
skyBoxShader = gltLoadShaderPairWithAttributes("SkyBox.vp", "SkyBox.fp", 2,
GLT_ATTRIBUTE_VERTEX, "vVertex",
GLT_ATTRIBUTE_NORMAL, "vNormal");
locMVPSkyBox = glGetUniformLocation(skyBoxShader, "mvpMatrix");
}
class CGLRenderModel
{
public:
CGLRenderModel(const std::string & sRenderModelName);
~CGLRenderModel();
bool BInit(const vr::RenderModel_t & vrModel, const vr::RenderModel_TextureMap_t & vrDiffuseTexture);
void Cleanup();
void Draw();
const std::string & GetName() const { return m_sModelName; }
private:
GLuint m_glVertBuffer;
GLuint m_glIndexBuffer;
GLuint m_glVertArray;
GLuint m_glTexture;
GLsizei m_unVertexCount;
std::string m_sModelName;
};
static bool g_bPrintf = true;
//-----------------------------------------------------------------------------
// Purpose:
//------------------------------------------------------------------------------
class CMainApplication
{
public:
CMainApplication(int argc, char *argv[]);
virtual ~CMainApplication();
bool BInit();
bool BInitGL();
bool BInitCompositor();
void SetupRenderModels();
void Shutdown();
void RunMainLoop();
bool HandleInput();
void ProcessVREvent(const vr::VREvent_t & event);
void RenderFrame();
bool SetupTexturemaps();
void SetupScene();
void AddCubeToScene(Matrix4 mat, std::vector &vertdata);
void AddCubeVertex(float fl0, float fl1, float fl2, float fl3, float fl4, std::vector &vertdata);
void RenderControllerAxes();
bool SetupStereoRenderTargets();
void SetupCompanionWindow();
void SetupCameras();
void RenderStereoTargets();
void RenderCompanionWindow();
void RenderScene(vr::Hmd_Eye nEye);
Matrix4 GetHMDMatrixProjectionEye(vr::Hmd_Eye nEye);
Matrix4 GetHMDMatrixPoseEye(vr::Hmd_Eye nEye);
Matrix4 GetCurrentViewProjectionMatrix(vr::Hmd_Eye nEye);
void UpdateHMDMatrixPose();
Matrix4 ConvertSteamVRMatrixToMatrix4(const vr::HmdMatrix34_t &matPose);
GLuint CompileGLShader(const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader);
bool CreateAllShaders();
void SetupRenderModelForTrackedDevice(vr::TrackedDeviceIndex_t unTrackedDeviceIndex);
CGLRenderModel *FindOrLoadRenderModel(const char *pchRenderModelName);
private:
bool m_bDebugOpenGL;
bool m_bVerbose;
bool m_bPerf;
bool m_bVblank;
bool m_bGlFinishHack;
vr::IVRSystem *m_pHMD;
vr::IVRRenderModels *m_pRenderModels;
std::string m_strDriver;
std::string m_strDisplay;
vr::TrackedDevicePose_t m_rTrackedDevicePose[vr::k_unMaxTrackedDeviceCount];
Matrix4 m_rmat4DevicePose[vr::k_unMaxTrackedDeviceCount];
bool m_rbShowTrackedDevice[vr::k_unMaxTrackedDeviceCount];
private: // SDL bookkeeping
SDL_Window * m_pCompanionWindow;
uint32_t m_nCompanionWindowWidth;
uint32_t m_nCompanionWindowHeight;
SDL_GLContext m_pContext;
private: // OpenGL bookkeeping
int m_iTrackedControllerCount;
int m_iTrackedControllerCount_Last;
int m_iValidPoseCount;
int m_iValidPoseCount_Last;
bool m_bShowCubes;
std::string m_strPoseClasses; // what classes we saw poses for this frame
char m_rDevClassChar[vr::k_unMaxTrackedDeviceCount]; // for each device, a character representing its class
int m_iSceneVolumeWidth;
int m_iSceneVolumeHeight;
int m_iSceneVolumeDepth;
float m_fScaleSpacing;
float m_fScale;
int m_iSceneVolumeInit; // if you want something other than the default 20x20x20
float m_fNearClip;
float m_fFarClip;
GLuint m_iTexture;
unsigned int m_uiVertcount;
GLuint m_glSceneVertBuffer;
GLuint m_unSceneVAO;
GLuint m_unCompanionWindowVAO;
GLuint m_glCompanionWindowIDVertBuffer;
GLuint m_glCompanionWindowIDIndexBuffer;
unsigned int m_uiCompanionWindowIndexSize;
GLuint m_glControllerVertBuffer;
GLuint m_unControllerVAO;
unsigned int m_uiControllerVertcount;
Matrix4 m_mat4HMDPose;
Matrix4 m_mat4eyePosLeft;
Matrix4 m_mat4eyePosRight;
Matrix4 m_mat4ProjectionCenter;
Matrix4 m_mat4ProjectionLeft;
Matrix4 m_mat4ProjectionRight;
struct VertexDataScene
{
Vector3 position;
Vector2 texCoord;
};
struct VertexDataWindow
{
Vector2 position;
Vector2 texCoord;
VertexDataWindow(const Vector2 & pos, const Vector2 tex) : position(pos), texCoord(tex) { }
};
GLuint m_unSceneProgramID;
GLuint m_unCompanionWindowProgramID;
GLuint m_unControllerTransformProgramID;
GLuint m_unRenderModelProgramID;
GLint m_nSceneMatrixLocation;
GLint m_nControllerMatrixLocation;
GLint m_nRenderModelMatrixLocation;
struct FramebufferDesc
{
GLuint m_nDepthBufferId;
GLuint m_nRenderTextureId;
GLuint m_nRenderFramebufferId;
GLuint m_nResolveTextureId;
GLuint m_nResolveFramebufferId;
};
FramebufferDesc leftEyeDesc;
FramebufferDesc rightEyeDesc;
bool CreateFrameBuffer(int nWidth, int nHeight, FramebufferDesc &framebufferDesc);
uint32_t m_nRenderWidth;
uint32_t m_nRenderHeight;
std::vector< CGLRenderModel * > m_vecRenderModels;
CGLRenderModel *m_rTrackedDeviceToRenderModel[vr::k_unMaxTrackedDeviceCount];
};
//-----------------------------------------------------------------------------
// Purpose: Outputs a set of optional arguments to debugging output, using
// the printf format setting specified in fmt*.
//-----------------------------------------------------------------------------
void dprintf(const char *fmt, ...)
{
va_list args;
char buffer[2048];
va_start(args, fmt);
vsprintf_s(buffer, fmt, args);
va_end(args);
if (g_bPrintf)
printf("%s", buffer);
OutputDebugStringA(buffer);
}
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CMainApplication::CMainApplication(int argc, char *argv[])
: m_pCompanionWindow(NULL)
, m_pContext(NULL)
, m_nCompanionWindowWidth(640)
, m_nCompanionWindowHeight(320)
, m_unSceneProgramID(0)
, m_unCompanionWindowProgramID(0)
, m_unControllerTransformProgramID(0)
, m_unRenderModelProgramID(0)
, m_pHMD(NULL)
, m_pRenderModels(NULL)
, m_bDebugOpenGL(false)
, m_bVerbose(false)
, m_bPerf(false)
, m_bVblank(false)
, m_bGlFinishHack(true)
, m_glControllerVertBuffer(0)
, m_unControllerVAO(0)
, m_unSceneVAO(0)
, m_nSceneMatrixLocation(-1)
, m_nControllerMatrixLocation(-1)
, m_nRenderModelMatrixLocation(-1)
, m_iTrackedControllerCount(0)
, m_iTrackedControllerCount_Last(-1)
, m_iValidPoseCount(0)
, m_iValidPoseCount_Last(-1)
, m_iSceneVolumeInit(20)
, m_strPoseClasses("")
, m_bShowCubes(true)
{
for (int i = 1; i < argc; i++)
{
if (!stricmp(argv[i], "-gldebug"))
{
m_bDebugOpenGL = true;
}
else if (!stricmp(argv[i], "-verbose"))
{
m_bVerbose = true;
}
else if (!stricmp(argv[i], "-novblank"))
{
m_bVblank = false;
}
else if (!stricmp(argv[i], "-noglfinishhack"))
{
m_bGlFinishHack = false;
}
else if (!stricmp(argv[i], "-noprintf"))
{
g_bPrintf = false;
}
else if (!stricmp(argv[i], "-cubevolume") && (argc > i + 1) && (*argv[i + 1] != '-'))
{
m_iSceneVolumeInit = atoi(argv[i + 1]);
i++;
}
}
// other initialization tasks are done in BInit
memset(m_rDevClassChar, 0, sizeof(m_rDevClassChar));
};
//-----------------------------------------------------------------------------
// Purpose: Destructor
//-----------------------------------------------------------------------------
CMainApplication::~CMainApplication()
{
// work is done in Shutdown
dprintf("Shutdown");
}
//-----------------------------------------------------------------------------
// Purpose: Helper to get a string from a tracked device property and turn it
// into a std::string
//-----------------------------------------------------------------------------
std::string GetTrackedDeviceString(vr::IVRSystem *pHmd, vr::TrackedDeviceIndex_t unDevice, vr::TrackedDeviceProperty prop, vr::TrackedPropertyError *peError = NULL)
{
uint32_t unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty(unDevice, prop, NULL, 0, peError);
if (unRequiredBufferLen == 0)
return "";
char *pchBuffer = new char[unRequiredBufferLen];
unRequiredBufferLen = pHmd->GetStringTrackedDeviceProperty(unDevice, prop, pchBuffer, unRequiredBufferLen, peError);
std::string sResult = pchBuffer;
delete[] pchBuffer;
return sResult;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CMainApplication::BInit()
{
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
{
printf("%s - SDL could not initialize! SDL Error: %s\n", __FUNCTION__, SDL_GetError());
return false;
}
// Loading the SteamVR Runtime
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));
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "VR_Init Failed", buf, NULL);
return false;
}
m_pRenderModels = (vr::IVRRenderModels *)vr::VR_GetGenericInterface(vr::IVRRenderModels_Version, &eError);
if (!m_pRenderModels)
{
m_pHMD = NULL;
vr::VR_Shutdown();
char buf[1024];
sprintf_s(buf, sizeof(buf), "Unable to get render model interface: %s", vr::VR_GetVRInitErrorAsEnglishDescription(eError));
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "VR_Init Failed", buf, NULL);
return false;
}
int nWindowPosX = 700;
int nWindowPosY = 100;
Uint32 unWindowFlags = SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN;
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 4);
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
//SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_COMPATIBILITY );
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
if (m_bDebugOpenGL)
SDL_GL_SetAttribute(SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG);
m_pCompanionWindow = SDL_CreateWindow("hellovr", nWindowPosX, nWindowPosY, m_nCompanionWindowWidth, m_nCompanionWindowHeight, unWindowFlags);
if (m_pCompanionWindow == NULL)
{
printf("%s - Window could not be created! SDL Error: %s\n", __FUNCTION__, SDL_GetError());
return false;
}
m_pContext = SDL_GL_CreateContext(m_pCompanionWindow);
if (m_pContext == NULL)
{
printf("%s - OpenGL context could not be created! SDL Error: %s\n", __FUNCTION__, SDL_GetError());
return false;
}
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
if (SDL_GL_SetSwapInterval(m_bVblank ? 1 : 0) < 0)
{
printf("%s - Warning: Unable to set VSync! SDL Error: %s\n", __FUNCTION__, SDL_GetError());
return false;
}
m_strDriver = "No Driver";
m_strDisplay = "No Display";
m_strDriver = GetTrackedDeviceString(m_pHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_TrackingSystemName_String);
m_strDisplay = GetTrackedDeviceString(m_pHMD, vr::k_unTrackedDeviceIndex_Hmd, vr::Prop_SerialNumber_String);
std::string strWindowTitle = "hellovr - " + m_strDriver + " " + m_strDisplay;
SDL_SetWindowTitle(m_pCompanionWindow, strWindowTitle.c_str());
// cube array
m_iSceneVolumeWidth = m_iSceneVolumeInit;
m_iSceneVolumeHeight = m_iSceneVolumeInit;
m_iSceneVolumeDepth = m_iSceneVolumeInit;
m_fScale = 0.3f;
m_fScaleSpacing = 4.0f;
m_fNearClip = 0.1f;
m_fFarClip = 30.0f;
m_iTexture = 0;
m_uiVertcount = 0;
// m_MillisecondsTimer.start(1, this);
// m_SecondsTimer.start(1000, this);
if (!BInitGL())
{
printf("%s - Unable to initialize OpenGL!\n", __FUNCTION__);
return false;
}
if (!BInitCompositor())
{
printf("%s - Failed to initialize VR Compositor!\n", __FUNCTION__);
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Outputs the string in message to debugging output.
// All other parameters are ignored.
// Does not return any meaningful value or reference.
//-----------------------------------------------------------------------------
void APIENTRY DebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char* message, const void* userParam)
{
dprintf("GL Error: %s\n", message);
}
//-----------------------------------------------------------------------------
// Purpose: Initialize OpenGL. Returns true if OpenGL has been successfully
// initialized, false if shaders could not be created.
// If failure occurred in a module other than shaders, the function
// may return true or throw an error.
//-----------------------------------------------------------------------------
bool CMainApplication::BInitGL()
{
if (m_bDebugOpenGL)
{
glDebugMessageCallback((GLDEBUGPROC)DebugCallback, nullptr);
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
}
if (!CreateAllShaders())
return false;
//SetupTexturemaps();
SetupScene();
SetupCameras();
SetupStereoRenderTargets();
SetupCompanionWindow();
SetupRenderModels();
return true;
}
//-----------------------------------------------------------------------------
// Purpose: Initialize Compositor. Returns true if the compositor was
// successfully initialized, false otherwise.
//-----------------------------------------------------------------------------
bool CMainApplication::BInitCompositor()
{
vr::EVRInitError peError = vr::VRInitError_None;
if (!vr::VRCompositor())
{
printf("Compositor initialization failed. See log file for details\n");
return false;
}
return true;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMainApplication::Shutdown()
{
if (m_pHMD)
{
vr::VR_Shutdown();
m_pHMD = NULL;
}
for (std::vector< CGLRenderModel * >::iterator i = m_vecRenderModels.begin(); i != m_vecRenderModels.end(); i++)
{
delete (*i);
}
m_vecRenderModels.clear();
if (m_pContext)
{
glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_FALSE);
glDebugMessageCallback(nullptr, nullptr);
glDeleteBuffers(1, &m_glSceneVertBuffer);
if (m_unSceneProgramID)
{
glDeleteProgram(m_unSceneProgramID);
}
if (m_unControllerTransformProgramID)
{
glDeleteProgram(m_unControllerTransformProgramID);
}
if (m_unRenderModelProgramID)
{
glDeleteProgram(m_unRenderModelProgramID);
}
if (m_unCompanionWindowProgramID)
{
glDeleteProgram(m_unCompanionWindowProgramID);
}
glDeleteRenderbuffers(1, &leftEyeDesc.m_nDepthBufferId);
glDeleteTextures(1, &leftEyeDesc.m_nRenderTextureId);
glDeleteFramebuffers(1, &leftEyeDesc.m_nRenderFramebufferId);
glDeleteTextures(1, &leftEyeDesc.m_nResolveTextureId);
glDeleteFramebuffers(1, &leftEyeDesc.m_nResolveFramebufferId);
glDeleteRenderbuffers(1, &rightEyeDesc.m_nDepthBufferId);
glDeleteTextures(1, &rightEyeDesc.m_nRenderTextureId);
glDeleteFramebuffers(1, &rightEyeDesc.m_nRenderFramebufferId);
glDeleteTextures(1, &rightEyeDesc.m_nResolveTextureId);
glDeleteFramebuffers(1, &rightEyeDesc.m_nResolveFramebufferId);
if (m_unCompanionWindowVAO != 0)
{
glDeleteVertexArrays(1, &m_unCompanionWindowVAO);
}
if (m_unSceneVAO != 0)
{
glDeleteVertexArrays(1, &m_unSceneVAO);
}
if (m_unControllerVAO != 0)
{
glDeleteVertexArrays(1, &m_unControllerVAO);
}
}
if (m_pCompanionWindow)
{
SDL_DestroyWindow(m_pCompanionWindow);
m_pCompanionWindow = NULL;
}
SDL_Quit();
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
bool CMainApplication::HandleInput()
{
SDL_Event sdlEvent;
bool bRet = false;
while (SDL_PollEvent(&sdlEvent) != 0)
{
if (sdlEvent.type == SDL_QUIT)
{
bRet = true;
}
else if (sdlEvent.type == SDL_KEYDOWN)
{
if (sdlEvent.key.keysym.sym == SDLK_ESCAPE
|| sdlEvent.key.keysym.sym == SDLK_q)
{
bRet = true;
}
if (sdlEvent.key.keysym.sym == SDLK_c)
{
m_bShowCubes = !m_bShowCubes;
}
}
}
// Process SteamVR events
vr::VREvent_t event;
while (m_pHMD->PollNextEvent(&event, sizeof(event)))
{
ProcessVREvent(event);
}
// Process SteamVR controller state
for (vr::TrackedDeviceIndex_t unDevice = 0; unDevice < vr::k_unMaxTrackedDeviceCount; unDevice++)
{
vr::VRControllerState_t state;
if (m_pHMD->GetControllerState(unDevice, &state, sizeof(state)))
{
m_rbShowTrackedDevice[unDevice] = state.ulButtonPressed == 0;
}
}
return bRet;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMainApplication::RunMainLoop()
{
bool bQuit = false;
SDL_StartTextInput();
SDL_ShowCursor(SDL_DISABLE);
while (!bQuit)
{
bQuit = HandleInput();
RenderFrame();
}
SDL_StopTextInput();
}
//-----------------------------------------------------------------------------
// Purpose: Processes a single VR event
//-----------------------------------------------------------------------------
void CMainApplication::ProcessVREvent(const vr::VREvent_t & event)
{
switch (event.eventType)
{
case vr::VREvent_TrackedDeviceActivated:
{
SetupRenderModelForTrackedDevice(event.trackedDeviceIndex);
dprintf("Device %u attached. Setting up render model.\n", event.trackedDeviceIndex);
}
break;
case vr::VREvent_TrackedDeviceDeactivated:
{
dprintf("Device %u detached.\n", event.trackedDeviceIndex);
}
break;
case vr::VREvent_TrackedDeviceUpdated:
{
dprintf("Device %u updated.\n", event.trackedDeviceIndex);
}
break;
}
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CMainApplication::RenderFrame()
{
// for now as fast as possible
if (m_pHMD)
{
RenderControllerAxes();
RenderStereoTargets();
RenderCompanionWindow();
vr::Texture_t leftEyeTexture = { (void*)(uintptr_t)leftEyeDesc.m_nResolveTextureId, vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
vr::VRCompositor()->Submit(vr::Eye_Left, &leftEyeTexture);
vr::Texture_t rightEyeTexture = { (void*)(uintptr_t)rightEyeDesc.m_nResolveTextureId, vr::TextureType_OpenGL, vr::ColorSpace_Gamma };
vr::VRCompositor()->Submit(vr::Eye_Right, &rightEyeTexture);
}
if (m_bVblank && m_bGlFinishHack)
{
//$ HACKHACK. From gpuview profiling, it looks like there is a bug where two renders and a present
// happen right before and after the vsync causing all kinds of jittering issues. This glFinish()
// appears to clear that up. Temporary fix while I try to get nvidia to investigate this problem.
// 1/29/2014 mikesart
glFinish();
}
// SwapWindow
{
SDL_GL_SwapWindow(m_pCompanionWindow);
}
// Clear
{
// We want to make sure the glFinish waits for the entire present to complete, not just the submission
// of the command. So, we do a clear here right here so the glFinish will wait fully for the swap.
glClearColor(0, 0, 0, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
}
// Flush and wait for swap.
if (m_bVblank)
{
glFlush();//强制刷新缓冲,保证绘图命令将被执行
glFinish();
}
// Spew out the controller and pose count whenever they change.
if (m_iTrackedControllerCount != m_iTrackedControllerCount_Last || m_iValidPoseCount != m_iValidPoseCount_Last)
{
m_iValidPoseCount_Last = m_iValidPoseCount;
m_iTrackedControllerCount_Last = m_iTrackedControllerCount;
dprintf("PoseCount:%d(%s) Controllers:%d\n", m_iValidPoseCount, m_strPoseClasses.c_str(), m_iTrackedControllerCount);
}
UpdateHMDMatrixPose();
}
//-----------------------------------------------------------------------------
// Purpose: Compiles a GL shader program and returns the handle. Returns 0 if
// the shader couldn't be compiled for some reason.
//-----------------------------------------------------------------------------
GLuint CMainApplication::CompileGLShader(const char *pchShaderName, const char *pchVertexShader, const char *pchFragmentShader)
{
GLuint unProgramID = glCreateProgram();
GLuint nSceneVertexShader = glCreateShader(GL_VERTEX_SHADER);
glShaderSource(nSceneVertexShader, 1, &pchVertexShader, NULL);
glCompileShader(nSceneVertexShader);
GLint vShaderCompiled = GL_FALSE;
glGetShaderiv(nSceneVertexShader, GL_COMPILE_STATUS, &vShaderCompiled);
if (vShaderCompiled != GL_TRUE)
{
dprintf("%s - Unable to compile vertex shader %d!\n", pchShaderName, nSceneVertexShader);
glDeleteProgram(unProgramID);
glDeleteShader(nSceneVertexShader);
return 0;
}
glAttachShader(unProgramID, nSceneVertexShader);
glDeleteShader(nSceneVertexShader); // the program hangs onto this once it's attached
GLuint nSceneFragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
glShaderSource(nSceneFragmentShader, 1, &pchFragmentShader, NULL);
glCompileShader(nSceneFragmentShader);
GLint fShaderCompiled = GL_FALSE;
glGetShaderiv(nSceneFragmentShader, GL_COMPILE_STATUS, &fShaderCompiled);
if (fShaderCompiled != GL_TRUE)
{
dprintf("%s - Unable to compile fragment shader %d!\n", pchShaderName, nSceneFragmentShader);
glDeleteProgram(unProgramID);
glDeleteShader(nSceneFragmentShader);
return 0;
}
glAttachShader(unProgramID, nSceneFragmentShader);
glDe