(三)代码b.0:hellovr_opengl

本文是OpenGL学习系列的第三部分,我们将探索如何使用OpenGL创建一个虚拟现实(VR)应用——HelloVR。通过这个项目,你将了解如何设置VR环境,结合OpenGL进行渲染,并体验VR的基本交互。
摘要由CSDN通过智能技术生成

    我主要也是看了各个主要函数调用关系,特别是和显示有关的,因为改代码基本就是在这些地方该。
    https://github.com/ValveSoftware/openvr/blob/master/samples/hellovr_opengl/hellovr_opengl_main.cpp
//========= Copyright Valve Corporation ============//



#include <SDL.h>

#include <GL/glew.h>

#include <SDL_opengl.h>

#if defined( OSX )

#include <Foundation/Foundation.h>

#include <AppKit/AppKit.h>

#include <OpenGL/glu.h>

// Apple's version of glut.h #undef's APIENTRY, redefine it

#define APIENTRY

#else

#include <GL/glu.h>

#endif

#include <stdio.h>

#include <string>

#include <cstdlib>



#include <openvr.h>



#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

}



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<float> &vertdata );

	void AddCubeVertex( float fl0, float fl1, float fl2, float fl3, float fl4, std::vector<float> &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 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值