mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2025-04-02 10:30:07 -04:00
Added OculusVR support.
This commit is contained in:
parent
e8ff46840e
commit
f6cf4df3d3
16 changed files with 1053 additions and 118 deletions
|
@ -103,15 +103,31 @@ int _main_(int /*_argc*/, char** /*_argv*/)
|
|||
while (!entry::processEvents(width, height, debug, reset) )
|
||||
{
|
||||
float view[16];
|
||||
float proj[16];
|
||||
bx::mtxLookAt(view, eye, at);
|
||||
bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
|
||||
|
||||
// Set view and projection matrix for view 0.
|
||||
bgfx::setViewTransform(0, view, proj);
|
||||
const bgfx::HMD* hmd = bgfx::getHMD();
|
||||
if (NULL != hmd)
|
||||
{
|
||||
float proj[16];
|
||||
bx::mtxProj(proj, hmd->eye[0].fov, 0.1f, 100.0f);
|
||||
bgfx::setViewTransform(0, view, proj);
|
||||
|
||||
// Set view 0 default viewport.
|
||||
bgfx::setViewRect(0, 0, 0, width, height);
|
||||
// Set view 0 default viewport.
|
||||
//
|
||||
// Use HMD's width/height since HMD's internal frame buffer size
|
||||
// might be much larger than window size.
|
||||
bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height);
|
||||
}
|
||||
else
|
||||
{
|
||||
float proj[16];
|
||||
bx::mtxProj(proj, 60.0f, float(width)/float(height), 0.1f, 100.0f);
|
||||
bgfx::setViewTransform(0, view, proj);
|
||||
|
||||
// Set view 0 default viewport.
|
||||
bgfx::setViewRect(0, 0, 0, width, height);
|
||||
}
|
||||
|
||||
// This dummy draw call is here to make sure that view 0 is cleared
|
||||
// if no other draw calls are submitted to view 0.
|
||||
|
|
|
@ -65,8 +65,10 @@ namespace entry
|
|||
{
|
||||
if (_argc > 1)
|
||||
{
|
||||
if (setOrToggle(s_reset, "vsync", BGFX_RESET_VSYNC, 1, _argc, _argv)
|
||||
|| setOrToggle(s_reset, "msaa", BGFX_RESET_MSAA_X16, 1, _argc, _argv) )
|
||||
if (setOrToggle(s_reset, "vsync", BGFX_RESET_VSYNC, 1, _argc, _argv)
|
||||
|| setOrToggle(s_reset, "hmd", BGFX_RESET_HMD, 1, _argc, _argv)
|
||||
|| setOrToggle(s_reset, "hmddbg", BGFX_RESET_HMD_DEBUG, 1, _argc, _argv)
|
||||
|| setOrToggle(s_reset, "msaa", BGFX_RESET_MSAA_X16, 1, _argc, _argv) )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -113,6 +115,7 @@ namespace entry
|
|||
{ entry::Key::F1, entry::Modifier::None, 1, cmd, "graphics stats" },
|
||||
{ entry::Key::F1, entry::Modifier::LeftShift, 1, cmd, "graphics stats 0\ngraphics text 0" },
|
||||
{ entry::Key::F3, entry::Modifier::None, 1, cmd, "graphics wireframe" },
|
||||
{ entry::Key::F4, entry::Modifier::None, 1, cmd, "graphics hmd" },
|
||||
{ entry::Key::F7, entry::Modifier::None, 1, cmd, "graphics vsync" },
|
||||
{ entry::Key::F8, entry::Modifier::None, 1, cmd, "graphics msaa" },
|
||||
{ entry::Key::Print, entry::Modifier::None, 1, cmd, "graphics screenshot" },
|
||||
|
|
|
@ -176,11 +176,32 @@ typedef struct bgfx_memory
|
|||
*/
|
||||
typedef struct bgfx_transform
|
||||
{
|
||||
float* data; //< Pointer to first matrix.
|
||||
uint16_t num; //< Number of matrices.
|
||||
float* data;
|
||||
uint16_t num;
|
||||
|
||||
} bgfx_transform_t;
|
||||
|
||||
/**
|
||||
*/
|
||||
typedef struct bgfx_hmd
|
||||
{
|
||||
/**
|
||||
* Eye
|
||||
*/
|
||||
struct Eye
|
||||
{
|
||||
float rotation[4];
|
||||
float translation[3];
|
||||
float fov[4];
|
||||
float adjust[3];
|
||||
float pixelsPerTanAngle[2];
|
||||
};
|
||||
|
||||
Eye eye[2];
|
||||
uint16_t width;
|
||||
uint16_t height;
|
||||
} bgfx_hmd_t;
|
||||
|
||||
/**
|
||||
* Vertex declaration.
|
||||
*/
|
||||
|
@ -566,7 +587,12 @@ BGFX_C_API bgfx_renderer_type_t bgfx_get_renderer_type();
|
|||
* NOTE:
|
||||
* Library must be initialized.
|
||||
*/
|
||||
BGFX_C_API bgfx_caps_t* bgfx_get_caps();
|
||||
BGFX_C_API const bgfx_caps_t* bgfx_get_caps();
|
||||
|
||||
/**
|
||||
* Returns HMD info.
|
||||
*/
|
||||
BGFX_C_API const bgfx_hmd_t* bgfx_get_hmd();
|
||||
|
||||
/**
|
||||
* Allocate buffer to pass to bgfx calls. Data will be freed inside bgfx.
|
||||
|
@ -1125,6 +1151,12 @@ BGFX_C_API void bgfx_set_view_frame_buffer(uint8_t _id, bgfx_frame_buffer_handle
|
|||
*/
|
||||
BGFX_C_API void bgfx_set_view_transform(uint8_t _id, const void* _view, const void* _proj);
|
||||
|
||||
/**
|
||||
* Set view view and projection matrices, all draw primitives in this
|
||||
* view will use these matrices.
|
||||
*/
|
||||
BGFX_C_API void bgfx_set_view_transform_stereo(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags, const void* _projR);
|
||||
|
||||
/**
|
||||
* Sets debug marker.
|
||||
*/
|
||||
|
|
|
@ -369,6 +369,24 @@ namespace bgfx
|
|||
uint16_t num; //!< Number of matrices.
|
||||
};
|
||||
|
||||
/// HMD info.
|
||||
struct HMD
|
||||
{
|
||||
/// Eye
|
||||
struct Eye
|
||||
{
|
||||
float rotation[4]; //!< Eye rotation represented as quaternion.
|
||||
float translation[3]; //!< Eye translation.
|
||||
float fov[4]; //!< Field of view (up, down, left, right).
|
||||
float adjust[3]; //!< Eye view matrix translation adjustment.
|
||||
float pixelsPerTanAngle[2]; //!<
|
||||
};
|
||||
|
||||
Eye eye[2];
|
||||
uint16_t width; //!< Framebuffer width.
|
||||
uint16_t height; //!< Framebuffer width.
|
||||
};
|
||||
|
||||
/// Vertex declaration.
|
||||
struct VertexDecl
|
||||
{
|
||||
|
@ -548,6 +566,9 @@ namespace bgfx
|
|||
///
|
||||
const Caps* getCaps();
|
||||
|
||||
/// Returns HMD info.
|
||||
const HMD* getHMD();
|
||||
|
||||
/// Allocate buffer to pass to bgfx calls. Data will be freed inside bgfx.
|
||||
const Memory* alloc(uint32_t _size);
|
||||
|
||||
|
@ -1038,7 +1059,7 @@ namespace bgfx
|
|||
|
||||
/// Set view view and projection matrices, all draw primitives in this
|
||||
/// view will use these matrices.
|
||||
void setViewTransform(uint8_t _id, const void* _view, const void* _proj);
|
||||
void setViewTransform(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags = BGFX_VIEW_STEREO, const void* _projR = NULL);
|
||||
|
||||
/// Sets debug marker.
|
||||
void setMarker(const char* _marker);
|
||||
|
|
|
@ -264,6 +264,8 @@
|
|||
#define BGFX_RESET_MSAA_MASK UINT32_C(0x00000070)
|
||||
#define BGFX_RESET_VSYNC UINT32_C(0x00000080)
|
||||
#define BGFX_RESET_CAPTURE UINT32_C(0x00000100)
|
||||
#define BGFX_RESET_HMD UINT32_C(0x00000200)
|
||||
#define BGFX_RESET_HMD_DEBUG UINT32_C(0x00000400)
|
||||
|
||||
///
|
||||
#define BGFX_CAPS_TEXTURE_COMPARE_LEQUAL UINT64_C(0x0000000000000001)
|
||||
|
@ -277,5 +279,10 @@
|
|||
#define BGFX_CAPS_COMPUTE UINT64_C(0x0000000000000100)
|
||||
#define BGFX_CAPS_FRAGMENT_ORDERING UINT64_C(0x0000000000000200)
|
||||
#define BGFX_CAPS_SWAP_CHAIN UINT64_C(0x0000000000000400)
|
||||
#define BGFX_CAPS_HMD UINT64_C(0x0000000000000800)
|
||||
|
||||
///
|
||||
#define BGFX_VIEW_NONE UINT8_C(0x00)
|
||||
#define BGFX_VIEW_STEREO UINT8_C(0x01)
|
||||
|
||||
#endif // BGFX_DEFINES_H_HEADER_GUARD
|
||||
|
|
27
src/bgfx.cpp
27
src/bgfx.cpp
|
@ -848,6 +848,9 @@ namespace bgfx
|
|||
CAPS_FLAGS(BGFX_CAPS_FRAGMENT_DEPTH),
|
||||
CAPS_FLAGS(BGFX_CAPS_BLEND_INDEPENDENT),
|
||||
CAPS_FLAGS(BGFX_CAPS_COMPUTE),
|
||||
CAPS_FLAGS(BGFX_CAPS_FRAGMENT_ORDERING),
|
||||
CAPS_FLAGS(BGFX_CAPS_SWAP_CHAIN),
|
||||
CAPS_FLAGS(BGFX_CAPS_HMD),
|
||||
#undef CAPS_FLAGS
|
||||
};
|
||||
|
||||
|
@ -1130,6 +1133,7 @@ namespace bgfx
|
|||
memcpy(m_submit->m_scissor, m_scissor, sizeof(m_scissor) );
|
||||
memcpy(m_submit->m_view, m_view, sizeof(m_view) );
|
||||
memcpy(m_submit->m_proj, m_proj, sizeof(m_proj) );
|
||||
memcpy(m_submit->m_viewFlags, m_viewFlags, sizeof(m_viewFlags) );
|
||||
if (m_clearColorDirty > 0)
|
||||
{
|
||||
--m_clearColorDirty;
|
||||
|
@ -1961,6 +1965,11 @@ again:
|
|||
return &g_caps;
|
||||
}
|
||||
|
||||
const HMD* getHMD()
|
||||
{
|
||||
return s_ctx->getHMD();
|
||||
}
|
||||
|
||||
RendererType::Enum getRendererType()
|
||||
{
|
||||
return g_caps.rendererType;
|
||||
|
@ -2557,10 +2566,10 @@ again:
|
|||
s_ctx->setViewFrameBuffer(_id, _handle);
|
||||
}
|
||||
|
||||
void setViewTransform(uint8_t _id, const void* _view, const void* _proj)
|
||||
void setViewTransform(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags, const void* _projR)
|
||||
{
|
||||
BGFX_CHECK_MAIN_THREAD();
|
||||
s_ctx->setViewTransform(_id, _view, _proj);
|
||||
s_ctx->setViewTransform(_id, _view, _projL, _flags, _projR);
|
||||
}
|
||||
|
||||
void setMarker(const char* _marker)
|
||||
|
@ -2853,9 +2862,14 @@ BGFX_C_API bgfx_renderer_type_t bgfx_get_renderer_type()
|
|||
return bgfx_renderer_type_t(bgfx::getRendererType() );
|
||||
}
|
||||
|
||||
BGFX_C_API bgfx_caps_t* bgfx_get_caps()
|
||||
BGFX_C_API const bgfx_caps_t* bgfx_get_caps()
|
||||
{
|
||||
return (bgfx_caps_t*)bgfx::getCaps();
|
||||
return (const bgfx_caps_t*)bgfx::getCaps();
|
||||
}
|
||||
|
||||
BGFX_C_API const bgfx_hmd_t* bgfx_get_hmd()
|
||||
{
|
||||
return (const bgfx_hmd_t*)bgfx::getHMD();
|
||||
}
|
||||
|
||||
BGFX_C_API const bgfx_memory_t* bgfx_alloc(uint32_t _size)
|
||||
|
@ -3195,6 +3209,11 @@ BGFX_C_API void bgfx_set_view_transform(uint8_t _id, const void* _view, const vo
|
|||
bgfx::setViewTransform(_id, _view, _proj);
|
||||
}
|
||||
|
||||
BGFX_C_API void bgfx_set_view_transform_stereo(uint8_t _id, const void* _view, const void* _projL, uint8_t _flags, const void* _projR)
|
||||
{
|
||||
bgfx::setViewTransform(_id, _view, _projL, _flags, _projR);
|
||||
}
|
||||
|
||||
BGFX_C_API void bgfx_set_marker(const char* _marker)
|
||||
{
|
||||
bgfx::setMarker(_marker);
|
||||
|
|
48
src/bgfx_p.h
48
src/bgfx_p.h
|
@ -72,6 +72,7 @@ namespace bgfx
|
|||
|
||||
#include <bx/bx.h>
|
||||
#include <bx/debug.h>
|
||||
#include <bx/fpumath.h>
|
||||
#include <bx/float4x4_t.h>
|
||||
#include <bx/blockalloc.h>
|
||||
#include <bx/endian.h>
|
||||
|
@ -1149,7 +1150,13 @@ namespace bgfx
|
|||
Frame()
|
||||
: m_waitSubmit(0)
|
||||
, m_waitRender(0)
|
||||
, m_hmdEnabled(false)
|
||||
{
|
||||
SortKey term;
|
||||
term.reset();
|
||||
term.m_program = invalidHandle;
|
||||
m_sortKeys[BGFX_CONFIG_MAX_DRAW_CALLS] = term.encodeDraw();
|
||||
m_sortValues[BGFX_CONFIG_MAX_DRAW_CALLS] = BGFX_CONFIG_MAX_DRAW_CALLS;
|
||||
}
|
||||
|
||||
~Frame()
|
||||
|
@ -1475,11 +1482,12 @@ namespace bgfx
|
|||
Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
|
||||
Rect m_scissor[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 m_view[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 m_proj[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 m_proj[2][BGFX_CONFIG_MAX_VIEWS];
|
||||
uint8_t m_viewFlags[BGFX_CONFIG_MAX_VIEWS];
|
||||
|
||||
uint64_t m_sortKeys[BGFX_CONFIG_MAX_DRAW_CALLS];
|
||||
uint16_t m_sortValues[BGFX_CONFIG_MAX_DRAW_CALLS];
|
||||
RenderItem m_renderItem[BGFX_CONFIG_MAX_DRAW_CALLS];
|
||||
uint64_t m_sortKeys[BGFX_CONFIG_MAX_DRAW_CALLS+1];
|
||||
uint16_t m_sortValues[BGFX_CONFIG_MAX_DRAW_CALLS+1];
|
||||
RenderItem m_renderItem[BGFX_CONFIG_MAX_DRAW_CALLS+1];
|
||||
RenderDraw m_draw;
|
||||
RenderCompute m_compute;
|
||||
uint64_t m_flags;
|
||||
|
@ -1525,6 +1533,8 @@ namespace bgfx
|
|||
FrameBufferHandle m_freeFrameBufferHandle[BGFX_CONFIG_MAX_FRAME_BUFFERS];
|
||||
UniformHandle m_freeUniformHandle[BGFX_CONFIG_MAX_UNIFORMS];
|
||||
TextVideoMem* m_textVideoMem;
|
||||
HMD m_hmd;
|
||||
bool m_hmdEnabled;
|
||||
|
||||
int64_t m_waitSubmit;
|
||||
int64_t m_waitRender;
|
||||
|
@ -1825,6 +1835,16 @@ namespace bgfx
|
|||
m_submit->m_textVideoMem->printfVargs(_x, _y, _attr, _format, _argList);
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(const HMD* getHMD() )
|
||||
{
|
||||
if (m_submit->m_hmdEnabled)
|
||||
{
|
||||
return &m_submit->m_hmd;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(IndexBufferHandle createIndexBuffer(const Memory* _mem) )
|
||||
{
|
||||
IndexBufferHandle handle = { m_indexBufferHandle.alloc() };
|
||||
|
@ -2733,8 +2753,10 @@ namespace bgfx
|
|||
m_fb[_id] = _handle;
|
||||
}
|
||||
|
||||
BGFX_API_FUNC(void setViewTransform(uint8_t _id, const void* _view, const void* _proj) )
|
||||
BGFX_API_FUNC(void setViewTransform(uint8_t _id, const void* _view, const void* _proj, uint8_t _flags, const void* _proj1) )
|
||||
{
|
||||
m_viewFlags[_id] = _flags;
|
||||
|
||||
if (NULL != _view)
|
||||
{
|
||||
memcpy(m_view[_id].un.val, _view, sizeof(Matrix4) );
|
||||
|
@ -2746,11 +2768,20 @@ namespace bgfx
|
|||
|
||||
if (NULL != _proj)
|
||||
{
|
||||
memcpy(m_proj[_id].un.val, _proj, sizeof(Matrix4) );
|
||||
memcpy(m_proj[0][_id].un.val, _proj, sizeof(Matrix4) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_proj[_id].setIdentity();
|
||||
m_proj[0][_id].setIdentity();
|
||||
}
|
||||
|
||||
if (NULL != _proj1)
|
||||
{
|
||||
memcpy(m_proj[1][_id].un.val, _proj1, sizeof(Matrix4) );
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(m_proj[1][_id].un.val, m_proj[0][_id].un.val, sizeof(Matrix4) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3041,7 +3072,8 @@ namespace bgfx
|
|||
Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
|
||||
Rect m_scissor[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 m_view[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 m_proj[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 m_proj[2][BGFX_CONFIG_MAX_VIEWS];
|
||||
uint8_t m_viewFlags[BGFX_CONFIG_MAX_VIEWS];
|
||||
uint16_t m_seq[BGFX_CONFIG_MAX_VIEWS];
|
||||
uint16_t m_seqMask[BGFX_CONFIG_MAX_VIEWS];
|
||||
|
||||
|
|
|
@ -117,6 +117,11 @@
|
|||
# define BGFX_CONFIG_USE_TINYSTL 1
|
||||
#endif // BGFX_CONFIG_USE_TINYSTL
|
||||
|
||||
/// Enable OculusVR integration.
|
||||
#ifndef BGFX_CONFIG_USE_OVR
|
||||
# define BGFX_CONFIG_USE_OVR 0
|
||||
#endif // BGFX_CONFIG_USE_OVR
|
||||
|
||||
/// Enable nVidia PerfHUD integration.
|
||||
#ifndef BGFX_CONFIG_DEBUG_PERFHUD
|
||||
# define BGFX_CONFIG_DEBUG_PERFHUD 0
|
||||
|
|
|
@ -42,6 +42,8 @@ namespace bgfx
|
|||
void makeCurrent()
|
||||
{
|
||||
wglMakeCurrent(m_hdc, m_context);
|
||||
GLenum err = glGetError();
|
||||
BX_WARN(0 == err, "wglMakeCurrent failed with GL error: 0x%04x.", err);
|
||||
}
|
||||
|
||||
void swapBuffers()
|
||||
|
@ -319,6 +321,8 @@ namespace bgfx
|
|||
if (NULL == _swapChain)
|
||||
{
|
||||
wglMakeCurrent(m_hdc, m_context);
|
||||
GLenum err = glGetError();
|
||||
BX_WARN(0 == err, "wglMakeCurrent failed with GL error: 0x%04x.", err);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
213
src/ovr.cpp
Normal file
213
src/ovr.cpp
Normal file
|
@ -0,0 +1,213 @@
|
|||
/*
|
||||
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "ovr.h"
|
||||
|
||||
#if BGFX_CONFIG_USE_OVR
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
OVR::OVR()
|
||||
: m_hmd(NULL)
|
||||
, m_initialized(false)
|
||||
{
|
||||
}
|
||||
|
||||
OVR::~OVR()
|
||||
{
|
||||
BX_CHECK(!m_initialized, "OVR not shutdown properly.");
|
||||
}
|
||||
|
||||
void OVR::init()
|
||||
{
|
||||
m_initialized = !!ovr_Initialize();
|
||||
}
|
||||
|
||||
void OVR::shutdown()
|
||||
{
|
||||
BX_CHECK(NULL == m_hmd, "HMD not destroyed.");
|
||||
ovr_Shutdown();
|
||||
m_initialized = false;
|
||||
}
|
||||
|
||||
bool OVR::postReset(void* _nwh, ovrRenderAPIConfig* _config, bool _debug)
|
||||
{
|
||||
if (!m_initialized)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!_debug)
|
||||
{
|
||||
m_hmd = ovrHmd_Create(0);
|
||||
}
|
||||
|
||||
if (NULL == m_hmd)
|
||||
{
|
||||
m_hmd = ovrHmd_CreateDebug(ovrHmd_DK2);
|
||||
BX_WARN(NULL != m_hmd, "Unable to initialize OVR.");
|
||||
|
||||
if (NULL == m_hmd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ovrBool result;
|
||||
result = ovrHmd_AttachToWindow(m_hmd, _nwh, NULL, NULL);
|
||||
if (!result) { goto ovrError; }
|
||||
|
||||
ovrFovPort eyeFov[2] = { m_hmd->DefaultEyeFov[0], m_hmd->DefaultEyeFov[1] };
|
||||
result = ovrHmd_ConfigureRendering(m_hmd
|
||||
, _config
|
||||
, 0
|
||||
| ovrDistortionCap_Chromatic
|
||||
| ovrDistortionCap_Vignette
|
||||
| ovrDistortionCap_TimeWarp
|
||||
| ovrDistortionCap_Overdrive
|
||||
, eyeFov
|
||||
, m_erd
|
||||
);
|
||||
if (!result) { goto ovrError; }
|
||||
|
||||
ovrHmd_SetEnabledCaps(m_hmd
|
||||
, 0
|
||||
| ovrHmdCap_LowPersistence
|
||||
| ovrHmdCap_DynamicPrediction
|
||||
);
|
||||
|
||||
result = ovrHmd_ConfigureTracking(m_hmd
|
||||
, 0
|
||||
| ovrTrackingCap_Orientation
|
||||
| ovrTrackingCap_MagYawCorrection
|
||||
| ovrTrackingCap_Position
|
||||
, 0
|
||||
);
|
||||
|
||||
if (!result)
|
||||
{
|
||||
ovrError:
|
||||
BX_TRACE("Failed to initialize OVR.");
|
||||
ovrHmd_Destroy(m_hmd);
|
||||
m_hmd = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
ovrSizei sizeL = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Left, m_hmd->DefaultEyeFov[0], 1.0f);
|
||||
ovrSizei sizeR = ovrHmd_GetFovTextureSize(m_hmd, ovrEye_Right, m_hmd->DefaultEyeFov[1], 1.0f);
|
||||
m_rtSize.w = sizeL.w + sizeR.w;
|
||||
m_rtSize.h = max(sizeL.h, sizeR.h);
|
||||
|
||||
m_warning = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OVR::postReset(ovrTexture _texture)
|
||||
{
|
||||
if (NULL != m_hmd)
|
||||
{
|
||||
m_texture[0] = _texture;
|
||||
m_texture[1] = _texture;
|
||||
|
||||
ovrRecti rect;
|
||||
rect.Pos.x = 0;
|
||||
rect.Pos.y = 0;
|
||||
rect.Size.w = m_rtSize.w/2;
|
||||
rect.Size.h = m_rtSize.h;
|
||||
|
||||
m_texture[0].Header.RenderViewport = rect;
|
||||
|
||||
rect.Pos.x += rect.Size.w;
|
||||
m_texture[1].Header.RenderViewport = rect;
|
||||
|
||||
m_timing = ovrHmd_BeginFrame(m_hmd, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void OVR::preReset()
|
||||
{
|
||||
if (NULL != m_hmd)
|
||||
{
|
||||
ovrHmd_EndFrame(m_hmd, m_pose, m_texture);
|
||||
ovrHmd_Destroy(m_hmd);
|
||||
m_hmd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
bool OVR::swap()
|
||||
{
|
||||
if (NULL == m_hmd)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ovrHmd_EndFrame(m_hmd, m_pose, m_texture);
|
||||
|
||||
if (m_warning)
|
||||
{
|
||||
m_warning = !ovrHmd_DismissHSWDisplay(m_hmd);
|
||||
}
|
||||
|
||||
m_timing = ovrHmd_BeginFrame(m_hmd, 0);
|
||||
|
||||
m_pose[0] = ovrHmd_GetEyePose(m_hmd, ovrEye_Left);
|
||||
m_pose[1] = ovrHmd_GetEyePose(m_hmd, ovrEye_Right);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void OVR::recenter()
|
||||
{
|
||||
if (NULL != m_hmd)
|
||||
{
|
||||
ovrHmd_RecenterPose(m_hmd);
|
||||
}
|
||||
}
|
||||
|
||||
void OVR::getEyePose(HMD& _hmd)
|
||||
{
|
||||
if (NULL != m_hmd)
|
||||
{
|
||||
ovrEyeType eye[2] = { ovrEye_Left, ovrEye_Right };
|
||||
for (int ii = 0; ii < 2; ++ii)
|
||||
{
|
||||
ovrPosef& pose = m_pose[ii];
|
||||
pose = ovrHmd_GetEyePose(m_hmd, eye[ii]);
|
||||
|
||||
HMD::Eye& eye = _hmd.eye[ii];
|
||||
eye.rotation[0] = pose.Orientation.x;
|
||||
eye.rotation[1] = pose.Orientation.y;
|
||||
eye.rotation[2] = pose.Orientation.z;
|
||||
eye.rotation[3] = pose.Orientation.w;
|
||||
eye.translation[0] = pose.Position.x;
|
||||
eye.translation[1] = pose.Position.y;
|
||||
eye.translation[2] = pose.Position.z;
|
||||
|
||||
const ovrEyeRenderDesc& erd = m_erd[ii];
|
||||
eye.fov[0] = erd.Fov.UpTan;
|
||||
eye.fov[1] = erd.Fov.DownTan;
|
||||
eye.fov[2] = erd.Fov.LeftTan;
|
||||
eye.fov[3] = erd.Fov.RightTan;
|
||||
eye.adjust[0] = erd.ViewAdjust.x;
|
||||
eye.adjust[1] = erd.ViewAdjust.y;
|
||||
eye.adjust[2] = erd.ViewAdjust.z;
|
||||
eye.pixelsPerTanAngle[0] = erd.PixelsPerTanAngleAtCenter.x;
|
||||
eye.pixelsPerTanAngle[1] = erd.PixelsPerTanAngleAtCenter.y;
|
||||
}
|
||||
|
||||
_hmd.width = uint16_t(m_rtSize.w);
|
||||
_hmd.height = uint16_t(m_rtSize.h);
|
||||
}
|
||||
else
|
||||
{
|
||||
_hmd.width = 0;
|
||||
_hmd.height = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
#endif // BGFX_CONFIG_USE_OVR
|
131
src/ovr.h
Normal file
131
src/ovr.h
Normal file
|
@ -0,0 +1,131 @@
|
|||
/*
|
||||
* Copyright 2011-2014 Branimir Karadzic. All rights reserved.
|
||||
* License: http://www.opensource.org/licenses/BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include "bgfx_p.h"
|
||||
|
||||
#if BGFX_CONFIG_USE_OVR
|
||||
|
||||
# include <OVR.h>
|
||||
|
||||
# if BGFX_CONFIG_RENDERER_DIRECT3D9
|
||||
# define OVR_D3D_VERSION 9
|
||||
# include <OVR_D3D.h>
|
||||
# endif // BGFX_CONFIG_RENDERER_DIRECT3D9
|
||||
|
||||
# if BGFX_CONFIG_RENDERER_DIRECT3D11
|
||||
# ifdef OVR_CAPI_D3D_h
|
||||
# undef OVR_CAPI_D3D_h
|
||||
# undef OVR_D3D_VERSION
|
||||
# endif // OVR_CAPI_D3D_h
|
||||
# define OVR_D3D_VERSION 11
|
||||
# include <OVR_D3D.h>
|
||||
# endif // BGFX_CONFIG_RENDERER_DIRECT3D11
|
||||
|
||||
# if BGFX_CONFIG_RENDERER_OPENGL
|
||||
# include <OVR_GL.h>
|
||||
# endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
struct OVR
|
||||
{
|
||||
OVR();
|
||||
~OVR();
|
||||
|
||||
bool isInitialized() const
|
||||
{
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
bool isEnabled() const
|
||||
{
|
||||
return NULL != m_hmd;
|
||||
}
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
|
||||
bool postReset(void* _nwh, ovrRenderAPIConfig* _config, bool _debug = false);
|
||||
void postReset(ovrTexture _texture);
|
||||
void preReset();
|
||||
bool swap();
|
||||
void recenter();
|
||||
void getEyePose(HMD& _hmd);
|
||||
void getSize(uint32_t& _width, uint32_t& _height) const
|
||||
{
|
||||
_width = m_rtSize.w;
|
||||
_height = m_rtSize.h;
|
||||
}
|
||||
|
||||
ovrHmd m_hmd;
|
||||
ovrFrameTiming m_timing;
|
||||
ovrEyeRenderDesc m_erd[2];
|
||||
ovrRecti m_rect[2];
|
||||
ovrPosef m_pose[2];
|
||||
ovrTexture m_texture[2];
|
||||
ovrSizei m_rtSize;
|
||||
bool m_warning;
|
||||
bool m_initialized;
|
||||
};
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
#else
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
struct OVR
|
||||
{
|
||||
OVR()
|
||||
{
|
||||
}
|
||||
|
||||
~OVR()
|
||||
{
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
}
|
||||
|
||||
bool isInitialized() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isEnabled() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool swap()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void recenter()
|
||||
{
|
||||
}
|
||||
|
||||
void getEyePose(HMD& _hmd)
|
||||
{
|
||||
_hmd.width = 0;
|
||||
_hmd.height = 0;
|
||||
}
|
||||
|
||||
void getSize(uint32_t& _width, uint32_t& _height) const
|
||||
{
|
||||
_width = 0;
|
||||
_height = 0;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace bgfx
|
||||
|
||||
#endif // BGFX_CONFIG_USE_OVR
|
|
@ -543,7 +543,10 @@ RENDERDOC_IMPORT
|
|||
struct RendererContextD3D11 : public RendererContextI
|
||||
{
|
||||
RendererContextD3D11()
|
||||
: m_lost(0)
|
||||
: m_renderdocdll(NULL)
|
||||
, m_lost(0)
|
||||
, m_backBufferColor(NULL)
|
||||
, m_backBufferDepthStencil(NULL)
|
||||
, m_captureTexture(NULL)
|
||||
, m_captureResolve(NULL)
|
||||
, m_wireframe(false)
|
||||
|
@ -551,6 +554,8 @@ RENDERDOC_IMPORT
|
|||
, m_vsChanges(0)
|
||||
, m_fsChanges(0)
|
||||
, m_rtMsaa(false)
|
||||
, m_ovrRtv(NULL)
|
||||
, m_ovrDsv(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -560,7 +565,13 @@ RENDERDOC_IMPORT
|
|||
|
||||
void init()
|
||||
{
|
||||
m_renderdocdll = loadRenderDoc();
|
||||
// Must be before device creation, and before RenderDoc.
|
||||
m_ovr.init();
|
||||
|
||||
if (!m_ovr.isInitialized() )
|
||||
{
|
||||
m_renderdocdll = loadRenderDoc();
|
||||
}
|
||||
|
||||
m_fbh.idx = invalidHandle;
|
||||
memset(m_uniforms, 0, sizeof(m_uniforms) );
|
||||
|
@ -761,6 +772,7 @@ RENDERDOC_IMPORT
|
|||
| BGFX_CAPS_COMPUTE
|
||||
| (getIntelExtensions(m_device) ? BGFX_CAPS_FRAGMENT_ORDERING : 0)
|
||||
| BGFX_CAPS_SWAP_CHAIN
|
||||
| (m_ovr.isInitialized() ? BGFX_CAPS_HMD : 0)
|
||||
);
|
||||
g_caps.maxTextureSize = D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION;
|
||||
g_caps.maxFBAttachments = bx::uint32_min(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT, BGFX_CONFIG_MAX_FRAME_BUFFER_ATTACHMENTS);
|
||||
|
@ -785,6 +797,7 @@ RENDERDOC_IMPORT
|
|||
void shutdown()
|
||||
{
|
||||
preReset();
|
||||
m_ovr.shutdown();
|
||||
|
||||
m_deviceCtx->ClearState();
|
||||
|
||||
|
@ -1074,6 +1087,10 @@ RENDERDOC_IMPORT
|
|||
|
||||
uint32_t width = m_scd.BufferDesc.Width;
|
||||
uint32_t height = m_scd.BufferDesc.Height;
|
||||
if (m_ovr.isEnabled() )
|
||||
{
|
||||
m_ovr.getSize(width, height);
|
||||
}
|
||||
|
||||
FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
|
||||
setFrameBuffer(fbh, false);
|
||||
|
@ -1139,6 +1156,8 @@ RENDERDOC_IMPORT
|
|||
|
||||
void preReset()
|
||||
{
|
||||
ovrPreReset();
|
||||
|
||||
DX_RELEASE(m_backBufferDepthStencil, 0);
|
||||
DX_RELEASE(m_backBufferColor, 0);
|
||||
|
||||
|
@ -1156,7 +1175,7 @@ RENDERDOC_IMPORT
|
|||
DX_RELEASE(color, 0);
|
||||
|
||||
D3D11_TEXTURE2D_DESC dsd;
|
||||
dsd.Width = m_scd.BufferDesc.Width;
|
||||
dsd.Width = m_scd.BufferDesc.Width;
|
||||
dsd.Height = m_scd.BufferDesc.Height;
|
||||
dsd.MipLevels = 1;
|
||||
dsd.ArraySize = 1;
|
||||
|
@ -1167,10 +1186,16 @@ RENDERDOC_IMPORT
|
|||
dsd.CPUAccessFlags = 0;
|
||||
dsd.MiscFlags = 0;
|
||||
|
||||
ID3D11Texture2D* depthStencil;
|
||||
DX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) );
|
||||
DX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_backBufferDepthStencil) );
|
||||
DX_RELEASE(depthStencil, 0);
|
||||
ovrPostReset();
|
||||
|
||||
// If OVR doesn't create separate depth stencil view, create default one.
|
||||
if (NULL == m_backBufferDepthStencil)
|
||||
{
|
||||
ID3D11Texture2D* depthStencil;
|
||||
DX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) );
|
||||
DX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_backBufferDepthStencil) );
|
||||
DX_RELEASE(depthStencil, 0);
|
||||
}
|
||||
|
||||
m_deviceCtx->OMSetRenderTargets(1, &m_backBufferColor, m_backBufferDepthStencil);
|
||||
|
||||
|
@ -1194,7 +1219,7 @@ RENDERDOC_IMPORT
|
|||
{
|
||||
if (NULL != m_swapChain)
|
||||
{
|
||||
HRESULT hr = 0;
|
||||
HRESULT hr = S_OK;
|
||||
uint32_t syncInterval = !!(m_flags & BGFX_RESET_VSYNC);
|
||||
for (uint32_t ii = 1, num = m_numWindows; ii < num && SUCCEEDED(hr); ++ii)
|
||||
{
|
||||
|
@ -1203,7 +1228,10 @@ RENDERDOC_IMPORT
|
|||
|
||||
if (SUCCEEDED(hr) )
|
||||
{
|
||||
hr = m_swapChain->Present(syncInterval, 0);
|
||||
if (!m_ovr.swap() )
|
||||
{
|
||||
hr = m_swapChain->Present(syncInterval, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (FAILED(hr)
|
||||
|
@ -1252,7 +1280,7 @@ RENDERDOC_IMPORT
|
|||
|
||||
void updateResolution(const Resolution& _resolution)
|
||||
{
|
||||
if ( (uint32_t)m_scd.BufferDesc.Width != _resolution.m_width
|
||||
if ( (uint32_t)m_scd.BufferDesc.Width != _resolution.m_width
|
||||
|| (uint32_t)m_scd.BufferDesc.Height != _resolution.m_height
|
||||
|| m_flags != _resolution.m_flags)
|
||||
{
|
||||
|
@ -1264,7 +1292,7 @@ RENDERDOC_IMPORT
|
|||
|
||||
m_resolution = _resolution;
|
||||
|
||||
m_scd.BufferDesc.Width = _resolution.m_width;
|
||||
m_scd.BufferDesc.Width = _resolution.m_width;
|
||||
m_scd.BufferDesc.Height = _resolution.m_height;
|
||||
|
||||
preReset();
|
||||
|
@ -1720,6 +1748,96 @@ RENDERDOC_IMPORT
|
|||
commitTextureStage();
|
||||
}
|
||||
|
||||
void ovrPostReset()
|
||||
{
|
||||
#if BGFX_CONFIG_USE_OVR
|
||||
if (m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
|
||||
{
|
||||
ovrD3D11Config config;
|
||||
config.D3D11.Header.API = ovrRenderAPI_D3D11;
|
||||
config.D3D11.Header.RTSize.w = m_scd.BufferDesc.Width;
|
||||
config.D3D11.Header.RTSize.h = m_scd.BufferDesc.Height;
|
||||
config.D3D11.Header.Multisample = 0;
|
||||
config.D3D11.pDevice = m_device;
|
||||
config.D3D11.pDeviceContext = m_deviceCtx;
|
||||
config.D3D11.pBackBufferRT = m_backBufferColor;
|
||||
config.D3D11.pSwapChain = m_swapChain;
|
||||
if (m_ovr.postReset(g_bgfxHwnd, &config.Config, !!(m_flags & BGFX_RESET_HMD_DEBUG) ) )
|
||||
{
|
||||
uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
|
||||
const Memory* mem = alloc(size);
|
||||
|
||||
bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
|
||||
uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
|
||||
bx::write(&writer, magic);
|
||||
|
||||
TextureCreate tc;
|
||||
tc.m_flags = BGFX_TEXTURE_RT;
|
||||
tc.m_width = m_ovr.m_rtSize.w;
|
||||
tc.m_height = m_ovr.m_rtSize.h;
|
||||
tc.m_sides = 0;
|
||||
tc.m_depth = 0;
|
||||
tc.m_numMips = 1;
|
||||
tc.m_format = uint8_t(bgfx::TextureFormat::BGRA8);
|
||||
tc.m_cubeMap = false;
|
||||
tc.m_mem = NULL;
|
||||
bx::write(&writer, tc);
|
||||
m_ovrRT.create(mem, tc.m_flags, 0);
|
||||
|
||||
release(mem);
|
||||
|
||||
DX_CHECK(m_device->CreateRenderTargetView(m_ovrRT.m_ptr, NULL, &m_ovrRtv) );
|
||||
|
||||
D3D11_TEXTURE2D_DESC dsd;
|
||||
dsd.Width = m_ovr.m_rtSize.w;
|
||||
dsd.Height = m_ovr.m_rtSize.h;
|
||||
dsd.MipLevels = 1;
|
||||
dsd.ArraySize = 1;
|
||||
dsd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
|
||||
dsd.SampleDesc = m_scd.SampleDesc;
|
||||
dsd.Usage = D3D11_USAGE_DEFAULT;
|
||||
dsd.BindFlags = D3D11_BIND_DEPTH_STENCIL;
|
||||
dsd.CPUAccessFlags = 0;
|
||||
dsd.MiscFlags = 0;
|
||||
|
||||
ID3D11Texture2D* depthStencil;
|
||||
DX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) );
|
||||
DX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_ovrDsv) );
|
||||
DX_RELEASE(depthStencil, 0);
|
||||
|
||||
ovrD3D11Texture texture;
|
||||
texture.D3D11.Header.API = ovrRenderAPI_D3D11;
|
||||
texture.D3D11.Header.TextureSize = m_ovr.m_rtSize;
|
||||
texture.D3D11.pTexture = m_ovrRT.m_texture2d;
|
||||
texture.D3D11.pSRView = m_ovrRT.m_srv;
|
||||
m_ovr.postReset(texture.Texture);
|
||||
|
||||
std::swap(m_ovrRtv, m_backBufferColor);
|
||||
|
||||
BX_CHECK(NULL == m_backBufferDepthStencil, "");
|
||||
std::swap(m_ovrDsv, m_backBufferDepthStencil);
|
||||
}
|
||||
}
|
||||
#endif // BGFX_CONFIG_USE_OVR
|
||||
}
|
||||
|
||||
void ovrPreReset()
|
||||
{
|
||||
#if BGFX_CONFIG_USE_OVR
|
||||
if (NULL != m_ovrRtv)
|
||||
{
|
||||
m_ovr.preReset();
|
||||
std::swap(m_ovrRtv, m_backBufferColor);
|
||||
std::swap(m_ovrDsv, m_backBufferDepthStencil);
|
||||
BX_CHECK(NULL == m_backBufferDepthStencil, "");
|
||||
|
||||
DX_RELEASE(m_ovrRtv, 0);
|
||||
DX_RELEASE(m_ovrDsv, 0);
|
||||
m_ovrRT.destroy();
|
||||
}
|
||||
#endif // BGFX_CONFIG_USE_OVR
|
||||
}
|
||||
|
||||
void capturePostReset()
|
||||
{
|
||||
if (m_flags&BGFX_RESET_CAPTURE)
|
||||
|
@ -2073,6 +2191,11 @@ RENDERDOC_IMPORT
|
|||
|
||||
FrameBufferHandle m_fbh;
|
||||
bool m_rtMsaa;
|
||||
|
||||
OVR m_ovr;
|
||||
TextureD3D11 m_ovrRT;
|
||||
ID3D11RenderTargetView* m_ovrRtv;
|
||||
ID3D11DepthStencilView* m_ovrDsv;
|
||||
};
|
||||
|
||||
static RendererContextD3D11* s_renderD3D11;
|
||||
|
@ -2816,18 +2939,63 @@ RENDERDOC_IMPORT
|
|||
currentState.m_flags = BGFX_STATE_NONE;
|
||||
currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
|
||||
|
||||
Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 mtxViewTmp[2][BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4* mtxView[2] = { _render->m_view, mtxViewTmp[1] };
|
||||
Matrix4 mtxViewProj[2][BGFX_CONFIG_MAX_VIEWS];
|
||||
|
||||
const bool hmdEnabled = m_ovr.isEnabled();
|
||||
_render->m_hmdEnabled = hmdEnabled;
|
||||
|
||||
if (hmdEnabled)
|
||||
{
|
||||
HMD& hmd = _render->m_hmd;
|
||||
m_ovr.getEyePose(hmd);
|
||||
|
||||
mtxView[0] = mtxViewTmp[0];
|
||||
Matrix4 viewAdjust;
|
||||
bx::mtxIdentity(viewAdjust.un.val);
|
||||
|
||||
for (uint32_t eye = 0; eye < 2; ++eye)
|
||||
{
|
||||
const HMD::Eye hmdEye = hmd.eye[eye];
|
||||
viewAdjust.un.val[12] = hmdEye.adjust[0];
|
||||
viewAdjust.un.val[13] = hmdEye.adjust[1];
|
||||
viewAdjust.un.val[14] = hmdEye.adjust[2];
|
||||
|
||||
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
|
||||
{
|
||||
if (BGFX_VIEW_STEREO == (_render->m_viewFlags[ii] & BGFX_VIEW_STEREO) )
|
||||
{
|
||||
bx::float4x4_mul(&mtxView[eye][ii].un.f4x4
|
||||
, &_render->m_view[ii].un.f4x4
|
||||
, &viewAdjust.un.f4x4
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&mtxView[0][ii].un.f4x4, &_render->m_view[ii].un.f4x4, sizeof(Matrix4) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
|
||||
{
|
||||
bx::float4x4_mul(&viewProj[ii].un.f4x4, &_render->m_view[ii].un.f4x4, &_render->m_proj[ii].un.f4x4);
|
||||
for (uint32_t eye = 0; eye < uint32_t(hmdEnabled)+1; ++eye)
|
||||
{
|
||||
bx::float4x4_mul(&mtxViewProj[eye][ii].un.f4x4
|
||||
, &mtxView[eye][ii].un.f4x4
|
||||
, &_render->m_proj[eye][ii].un.f4x4
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Matrix4 invView;
|
||||
Matrix4 invProj;
|
||||
Matrix4 invViewProj;
|
||||
uint8_t invViewCached = 0xff;
|
||||
uint8_t invProjCached = 0xff;
|
||||
uint8_t invViewProjCached = 0xff;
|
||||
uint16_t invViewCached = UINT16_MAX;
|
||||
uint16_t invProjCached = UINT16_MAX;
|
||||
uint16_t invViewProjCached = UINT16_MAX;
|
||||
|
||||
bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);
|
||||
bool scissorEnabled = false;
|
||||
|
@ -2856,17 +3024,33 @@ RENDERDOC_IMPORT
|
|||
|
||||
if (0 == (_render->m_debug&BGFX_DEBUG_IFH) )
|
||||
{
|
||||
for (uint32_t item = 0, numItems = _render->m_num; item < numItems; ++item)
|
||||
bool viewRestart = false;
|
||||
uint8_t eye = 0;
|
||||
uint8_t restartState = 0;
|
||||
Rect rect = _render->m_rect[0];
|
||||
|
||||
int32_t numItems = _render->m_num;
|
||||
for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;)
|
||||
{
|
||||
const bool isCompute = key.decode(_render->m_sortKeys[item]);
|
||||
const bool viewChanged = key.m_view != view;
|
||||
const bool viewChanged = 0
|
||||
|| key.m_view != view
|
||||
|| item == numItems
|
||||
;
|
||||
|
||||
const RenderItem& renderItem = _render->m_renderItem[_render->m_sortValues[item] ];
|
||||
++item;
|
||||
|
||||
if (viewChanged)
|
||||
{
|
||||
PIX_ENDEVENT();
|
||||
PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), s_viewNameW[key.m_view]);
|
||||
if (1 == restartState)
|
||||
{
|
||||
restartState = 2;
|
||||
item = restartItem;
|
||||
restartItem = numItems;
|
||||
view = 0xff;
|
||||
continue;
|
||||
}
|
||||
|
||||
view = key.m_view;
|
||||
programIdx = invalidHandle;
|
||||
|
@ -2877,7 +3061,43 @@ RENDERDOC_IMPORT
|
|||
setFrameBuffer(fbh);
|
||||
}
|
||||
|
||||
const Rect& rect = _render->m_rect[view];
|
||||
viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_viewFlags[view] & BGFX_VIEW_STEREO) ) );
|
||||
viewRestart &= hmdEnabled;
|
||||
if (viewRestart)
|
||||
{
|
||||
if (0 == restartState)
|
||||
{
|
||||
restartState = 1;
|
||||
restartItem = item - 1;
|
||||
}
|
||||
|
||||
eye = (restartState - 1) & 1;
|
||||
restartState &= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
eye = 0;
|
||||
}
|
||||
|
||||
PIX_ENDEVENT();
|
||||
|
||||
rect = _render->m_rect[view];
|
||||
if (viewRestart)
|
||||
{
|
||||
wchar_t* viewNameW = s_viewNameW[view];
|
||||
viewNameW[3] = eye ? L'R' : L'L';
|
||||
PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), viewNameW);
|
||||
|
||||
rect.m_x = eye * (rect.m_width+1)/2;
|
||||
rect.m_width /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t* viewNameW = s_viewNameW[view];
|
||||
viewNameW[3] = L' ';
|
||||
PIX_BEGINEVENT(D3DCOLOR_RGBA(0xff, 0x00, 0x00, 0xff), viewNameW);
|
||||
}
|
||||
|
||||
const Rect& scissorRect = _render->m_scissor[view];
|
||||
viewHasScissor = !scissorRect.isZero();
|
||||
viewScissorRect = viewHasScissor ? scissorRect : rect;
|
||||
|
@ -3194,38 +3414,43 @@ RENDERDOC_IMPORT
|
|||
{
|
||||
case PredefinedUniform::ViewRect:
|
||||
{
|
||||
float rect[4];
|
||||
rect[0] = _render->m_rect[view].m_x;
|
||||
rect[1] = _render->m_rect[view].m_y;
|
||||
rect[2] = _render->m_rect[view].m_width;
|
||||
rect[3] = _render->m_rect[view].m_height;
|
||||
float frect[4];
|
||||
frect[0] = rect.m_x;
|
||||
frect[1] = rect.m_y;
|
||||
frect[2] = rect.m_width;
|
||||
frect[3] = rect.m_height;
|
||||
|
||||
setShaderConstant(flags, predefined.m_loc, &rect[0], 1);
|
||||
setShaderConstant(flags, predefined.m_loc, &frect[0], 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::ViewTexel:
|
||||
{
|
||||
float rect[4];
|
||||
rect[0] = 1.0f/float(_render->m_rect[view].m_width);
|
||||
rect[1] = 1.0f/float(_render->m_rect[view].m_height);
|
||||
float frect[4];
|
||||
frect[0] = 1.0f/float(rect.m_width);
|
||||
frect[1] = 1.0f/float(rect.m_height);
|
||||
|
||||
setShaderConstant(flags, predefined.m_loc, &rect[0], 1);
|
||||
setShaderConstant(flags, predefined.m_loc, &frect[0], 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::View:
|
||||
{
|
||||
setShaderConstant(flags, predefined.m_loc, _render->m_view[view].un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
setShaderConstant(flags
|
||||
, predefined.m_loc
|
||||
, mtxView[eye][view].un.val
|
||||
, bx::uint32_min(4, predefined.m_count)
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::InvView:
|
||||
{
|
||||
if (view != invViewCached)
|
||||
uint16_t viewEye = (view << 1) | eye;
|
||||
if (viewEye != invViewCached)
|
||||
{
|
||||
invViewCached = view;
|
||||
bx::float4x4_inverse(&invView.un.f4x4, &_render->m_view[view].un.f4x4);
|
||||
invViewCached = viewEye;
|
||||
bx::float4x4_inverse(&invView.un.f4x4, &mtxView[eye][view].un.f4x4);
|
||||
}
|
||||
|
||||
setShaderConstant(flags, predefined.m_loc, invView.un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
|
@ -3234,16 +3459,17 @@ RENDERDOC_IMPORT
|
|||
|
||||
case PredefinedUniform::Proj:
|
||||
{
|
||||
setShaderConstant(flags, predefined.m_loc, _render->m_proj[view].un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
setShaderConstant(flags, predefined.m_loc, _render->m_proj[eye][view].un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::InvProj:
|
||||
{
|
||||
if (view != invProjCached)
|
||||
uint16_t viewEye = (view << 1) | eye;
|
||||
if (viewEye != invProjCached)
|
||||
{
|
||||
invProjCached = view;
|
||||
bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[view].un.f4x4);
|
||||
invProjCached = viewEye;
|
||||
bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[eye][view].un.f4x4);
|
||||
}
|
||||
|
||||
setShaderConstant(flags, predefined.m_loc, invProj.un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
|
@ -3252,16 +3478,17 @@ RENDERDOC_IMPORT
|
|||
|
||||
case PredefinedUniform::ViewProj:
|
||||
{
|
||||
setShaderConstant(flags, predefined.m_loc, viewProj[view].un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
setShaderConstant(flags, predefined.m_loc, mtxViewProj[eye][view].un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::InvViewProj:
|
||||
{
|
||||
if (view != invViewProjCached)
|
||||
uint16_t viewEye = (view << 1) | eye;
|
||||
if (viewEye != invViewProjCached)
|
||||
{
|
||||
invViewProjCached = view;
|
||||
bx::float4x4_inverse(&invViewProj.un.f4x4, &viewProj[view].un.f4x4);
|
||||
invViewProjCached = viewEye;
|
||||
bx::float4x4_inverse(&invViewProj.un.f4x4, &mtxViewProj[eye][view].un.f4x4);
|
||||
}
|
||||
|
||||
setShaderConstant(flags, predefined.m_loc, invViewProj.un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
|
@ -3279,7 +3506,7 @@ RENDERDOC_IMPORT
|
|||
{
|
||||
Matrix4 modelView;
|
||||
const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
|
||||
bx::float4x4_mul(&modelView.un.f4x4, &model.un.f4x4, &_render->m_view[view].un.f4x4);
|
||||
bx::float4x4_mul(&modelView.un.f4x4, &model.un.f4x4, &mtxView[eye][view].un.f4x4);
|
||||
setShaderConstant(flags, predefined.m_loc, modelView.un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
}
|
||||
break;
|
||||
|
@ -3288,7 +3515,7 @@ RENDERDOC_IMPORT
|
|||
{
|
||||
Matrix4 modelViewProj;
|
||||
const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
|
||||
bx::float4x4_mul(&modelViewProj.un.f4x4, &model.un.f4x4, &viewProj[view].un.f4x4);
|
||||
bx::float4x4_mul(&modelViewProj.un.f4x4, &model.un.f4x4, &mtxViewProj[eye][view].un.f4x4);
|
||||
setShaderConstant(flags, predefined.m_loc, modelViewProj.un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
}
|
||||
break;
|
||||
|
@ -3540,11 +3767,15 @@ RENDERDOC_IMPORT
|
|||
, freq/frameTime
|
||||
);
|
||||
|
||||
char hmd[16];
|
||||
bx::snprintf(hmd, BX_COUNTOF(hmd), ", [%c] HMD ", hmdEnabled ? '\xfe' : ' ');
|
||||
|
||||
const uint32_t msaa = (m_resolution.m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT;
|
||||
tvm.printf(10, pos++, 0x8e, " Reset flags: [%c] vsync, [%c] MSAAx%d "
|
||||
tvm.printf(10, pos++, 0x8e, " Reset flags: [%c] vsync, [%c] MSAAx%d%s"
|
||||
, !!(m_resolution.m_flags&BGFX_RESET_VSYNC) ? '\xfe' : ' '
|
||||
, 0 != msaa ? '\xfe' : ' '
|
||||
, 1<<msaa
|
||||
, m_ovr.isInitialized() ? hmd : ", no-HMD "
|
||||
);
|
||||
|
||||
double elapsedCpuMs = double(elapsed)*toMs;
|
||||
|
|
|
@ -22,9 +22,15 @@ BX_PRAGMA_DIAGNOSTIC_IGNORED_MSVC(4005) // warning C4005: '' : macro redefinitio
|
|||
BX_PRAGMA_DIAGNOSTIC_POP()
|
||||
|
||||
#include "renderer_d3d.h"
|
||||
#include "ovr.h"
|
||||
|
||||
#define D3DCOLOR_ARGB(_a, _r, _g, _b) ( (DWORD)( ( ( (_a)&0xff)<<24)|( ( (_r)&0xff)<<16)|( ( (_g)&0xff)<<8)|( (_b)&0xff) ) )
|
||||
#define D3DCOLOR_RGBA(_r, _g, _b, _a) D3DCOLOR_ARGB(_a, _r, _g, _b)
|
||||
#ifndef D3DCOLOR_ARGB
|
||||
# define D3DCOLOR_ARGB(_a, _r, _g, _b) ( (DWORD)( ( ( (_a)&0xff)<<24)|( ( (_r)&0xff)<<16)|( ( (_g)&0xff)<<8)|( (_b)&0xff) ) )
|
||||
#endif // D3DCOLOR_ARGB
|
||||
|
||||
#ifndef D3DCOLOR_RGBA
|
||||
# define D3DCOLOR_RGBA(_r, _g, _b, _a) D3DCOLOR_ARGB(_a, _r, _g, _b)
|
||||
#endif // D3DCOLOR_RGBA
|
||||
|
||||
namespace bgfx
|
||||
{
|
||||
|
|
|
@ -2815,7 +2815,7 @@ namespace bgfx
|
|||
Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
|
||||
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
|
||||
{
|
||||
bx::float4x4_mul(&viewProj[ii].un.f4x4, &_render->m_view[ii].un.f4x4, &_render->m_proj[ii].un.f4x4);
|
||||
bx::float4x4_mul(&viewProj[ii].un.f4x4, &_render->m_view[ii].un.f4x4, &_render->m_proj[0][ii].un.f4x4);
|
||||
}
|
||||
|
||||
Matrix4 invView;
|
||||
|
@ -3212,7 +3212,7 @@ namespace bgfx
|
|||
|
||||
case PredefinedUniform::Proj:
|
||||
{
|
||||
setShaderConstantF(flags, predefined.m_loc, _render->m_proj[view].un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
setShaderConstantF(flags, predefined.m_loc, _render->m_proj[0][view].un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -3221,7 +3221,7 @@ namespace bgfx
|
|||
if (view != invProjCached)
|
||||
{
|
||||
invProjCached = view;
|
||||
bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[view].un.f4x4);
|
||||
bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[0][view].un.f4x4);
|
||||
}
|
||||
|
||||
setShaderConstantF(flags, predefined.m_loc, invProj.un.val, bx::uint32_min(4, predefined.m_count) );
|
||||
|
|
|
@ -854,6 +854,7 @@ namespace bgfx
|
|||
, m_hash( (BX_PLATFORM_WINDOWS<<1) | BX_ARCH_64BIT)
|
||||
, m_backBufferFbo(0)
|
||||
, m_msaaBackBufferFbo(0)
|
||||
, m_ovrFbo(0)
|
||||
{
|
||||
memset(m_msaaBackBufferRbos, 0, sizeof(m_msaaBackBufferRbos) );
|
||||
}
|
||||
|
@ -870,6 +871,9 @@ namespace bgfx
|
|||
|
||||
setRenderContextSize(BGFX_DEFAULT_WIDTH, BGFX_DEFAULT_HEIGHT);
|
||||
|
||||
// Must be after context is initialized?!
|
||||
m_ovr.init();
|
||||
|
||||
m_vendor = getGLString(GL_VENDOR);
|
||||
m_renderer = getGLString(GL_RENDERER);
|
||||
m_version = getGLString(GL_VERSION);
|
||||
|
@ -1364,10 +1368,15 @@ namespace bgfx
|
|||
{
|
||||
bx::snprintf(s_viewName[ii], BGFX_CONFIG_MAX_VIEW_NAME_RESERVED+1, "%3d ", ii);
|
||||
}
|
||||
|
||||
ovrPostReset();
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
ovrPreReset();
|
||||
m_ovr.shutdown();
|
||||
|
||||
if (m_vaoSupport)
|
||||
{
|
||||
GL_CHECK(glBindVertexArray(0) );
|
||||
|
@ -1413,7 +1422,11 @@ namespace bgfx
|
|||
{
|
||||
m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain);
|
||||
}
|
||||
m_glctx.swap();
|
||||
|
||||
if (!m_ovr.swap() )
|
||||
{
|
||||
m_glctx.swap();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1575,7 +1588,7 @@ namespace bgfx
|
|||
uint32_t length = m_resolution.m_width*m_resolution.m_height*4;
|
||||
uint8_t* data = (uint8_t*)BX_ALLOC(g_allocator, length);
|
||||
|
||||
uint32_t width = m_resolution.m_width;
|
||||
uint32_t width = m_resolution.m_width;
|
||||
uint32_t height = m_resolution.m_height;
|
||||
|
||||
GL_CHECK(glReadPixels(0
|
||||
|
@ -1630,8 +1643,12 @@ namespace bgfx
|
|||
GL_CHECK(glBindVertexArray(m_vao) );
|
||||
}
|
||||
|
||||
uint32_t width = m_resolution.m_width;
|
||||
uint32_t width = m_resolution.m_width;
|
||||
uint32_t height = m_resolution.m_height;
|
||||
if (m_ovr.isEnabled() )
|
||||
{
|
||||
m_ovr.getSize(width, height);
|
||||
}
|
||||
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_backBufferFbo) );
|
||||
GL_CHECK(glViewport(0, 0, width, height) );
|
||||
|
@ -1685,9 +1702,9 @@ namespace bgfx
|
|||
|
||||
void updateResolution(const Resolution& _resolution)
|
||||
{
|
||||
if (m_resolution.m_width != _resolution.m_width
|
||||
if (m_resolution.m_width != _resolution.m_width
|
||||
|| m_resolution.m_height != _resolution.m_height
|
||||
|| m_resolution.m_flags != _resolution.m_flags)
|
||||
|| m_resolution.m_flags != _resolution.m_flags)
|
||||
{
|
||||
m_textVideoMem.resize(false, _resolution.m_width, _resolution.m_height);
|
||||
m_textVideoMem.clear();
|
||||
|
@ -1699,6 +1716,9 @@ namespace bgfx
|
|||
bool vsync = !!(m_resolution.m_flags&BGFX_RESET_VSYNC);
|
||||
setRenderContextSize(_resolution.m_width, _resolution.m_height, msaa, vsync);
|
||||
updateCapture();
|
||||
|
||||
ovrPreReset();
|
||||
ovrPostReset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1806,7 +1826,7 @@ namespace bgfx
|
|||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_backBufferFbo) );
|
||||
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_msaaBackBufferFbo) );
|
||||
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) );
|
||||
uint32_t width = m_resolution.m_width;
|
||||
uint32_t width = m_resolution.m_width;
|
||||
uint32_t height = m_resolution.m_height;
|
||||
GLenum filter = BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGL) || BX_ENABLED(BGFX_CONFIG_RENDERER_OPENGLES < 30)
|
||||
? GL_NEAREST
|
||||
|
@ -1925,6 +1945,81 @@ namespace bgfx
|
|||
}
|
||||
}
|
||||
|
||||
void ovrPostReset()
|
||||
{
|
||||
#if BGFX_CONFIG_USE_OVR
|
||||
if (m_resolution.m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
|
||||
{
|
||||
ovrGLConfig config;
|
||||
config.OGL.Header.API = ovrRenderAPI_OpenGL;
|
||||
config.OGL.Header.RTSize.w = m_resolution.m_width;
|
||||
config.OGL.Header.RTSize.h = m_resolution.m_height;
|
||||
config.OGL.Header.Multisample = 0;
|
||||
config.OGL.Window = g_bgfxHwnd;
|
||||
config.OGL.DC = GetDC(g_bgfxHwnd);
|
||||
if (m_ovr.postReset(g_bgfxHwnd, &config.Config, !!(m_resolution.m_flags & BGFX_RESET_HMD_DEBUG) ) )
|
||||
{
|
||||
uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
|
||||
const Memory* mem = alloc(size);
|
||||
|
||||
bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
|
||||
uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
|
||||
bx::write(&writer, magic);
|
||||
|
||||
TextureCreate tc;
|
||||
tc.m_flags = BGFX_TEXTURE_RT;
|
||||
tc.m_width = m_ovr.m_rtSize.w;
|
||||
tc.m_height = m_ovr.m_rtSize.h;
|
||||
tc.m_sides = 0;
|
||||
tc.m_depth = 0;
|
||||
tc.m_numMips = 1;
|
||||
tc.m_format = uint8_t(bgfx::TextureFormat::BGRA8);
|
||||
tc.m_cubeMap = false;
|
||||
tc.m_mem = NULL;
|
||||
bx::write(&writer, tc);
|
||||
|
||||
m_ovrRT.create(mem, tc.m_flags, 0);
|
||||
release(mem);
|
||||
|
||||
m_ovrFbo = m_msaaBackBufferFbo;
|
||||
|
||||
GL_CHECK(glGenFramebuffers(1, &m_msaaBackBufferFbo) );
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
|
||||
|
||||
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER
|
||||
, GL_COLOR_ATTACHMENT0
|
||||
, GL_TEXTURE_2D
|
||||
, m_ovrRT.m_id
|
||||
, 0
|
||||
) );
|
||||
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_ovrFbo) );
|
||||
|
||||
ovrGLTexture texture;
|
||||
texture.OGL.Header.API = ovrRenderAPI_OpenGL;
|
||||
texture.OGL.Header.TextureSize = m_ovr.m_rtSize;
|
||||
texture.OGL.TexId = m_ovrRT.m_id;
|
||||
m_ovr.postReset(texture.Texture);
|
||||
}
|
||||
}
|
||||
#endif // BGFX_CONFIG_USE_OVR
|
||||
}
|
||||
|
||||
void ovrPreReset()
|
||||
{
|
||||
#if BGFX_CONFIG_USE_OVR
|
||||
if (m_ovr.isEnabled() )
|
||||
{
|
||||
m_ovr.preReset();
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
|
||||
GL_CHECK(glDeleteFramebuffers(1, &m_msaaBackBufferFbo) );
|
||||
m_msaaBackBufferFbo = m_ovrFbo;
|
||||
m_ovrFbo = 0;
|
||||
m_ovrRT.destroy();
|
||||
}
|
||||
#endif // BGFX_CONFIG_USE_OVR
|
||||
}
|
||||
|
||||
void updateCapture()
|
||||
{
|
||||
if (m_resolution.m_flags&BGFX_RESET_CAPTURE)
|
||||
|
@ -2324,6 +2419,10 @@ namespace bgfx
|
|||
const char* m_renderer;
|
||||
const char* m_version;
|
||||
const char* m_glslVersion;
|
||||
|
||||
OVR m_ovr;
|
||||
TextureGL m_ovrRT;
|
||||
GLint m_ovrFbo;
|
||||
};
|
||||
|
||||
RendererContextGL* s_renderGL;
|
||||
|
@ -4009,24 +4108,73 @@ namespace bgfx
|
|||
currentState.m_flags = BGFX_STATE_NONE;
|
||||
currentState.m_stencil = packStencil(BGFX_STENCIL_NONE, BGFX_STENCIL_NONE);
|
||||
|
||||
Matrix4 viewProj[BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4 mtxViewTmp[2][BGFX_CONFIG_MAX_VIEWS];
|
||||
Matrix4* mtxView[2] = { _render->m_view, mtxViewTmp[1] };
|
||||
Matrix4 mtxViewProj[2][BGFX_CONFIG_MAX_VIEWS];
|
||||
|
||||
const bool hmdEnabled = m_ovr.isEnabled();
|
||||
_render->m_hmdEnabled = hmdEnabled;
|
||||
|
||||
if (hmdEnabled)
|
||||
{
|
||||
HMD& hmd = _render->m_hmd;
|
||||
m_ovr.getEyePose(hmd);
|
||||
|
||||
mtxView[0] = mtxViewTmp[0];
|
||||
Matrix4 viewAdjust;
|
||||
bx::mtxIdentity(viewAdjust.un.val);
|
||||
|
||||
for (uint32_t eye = 0; eye < 2; ++eye)
|
||||
{
|
||||
const HMD::Eye hmdEye = hmd.eye[eye];
|
||||
viewAdjust.un.val[12] = hmdEye.adjust[0];
|
||||
viewAdjust.un.val[13] = hmdEye.adjust[1];
|
||||
viewAdjust.un.val[14] = hmdEye.adjust[2];
|
||||
|
||||
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
|
||||
{
|
||||
if (BGFX_VIEW_STEREO == (_render->m_viewFlags[ii] & BGFX_VIEW_STEREO) )
|
||||
{
|
||||
bx::float4x4_mul(&mtxView[eye][ii].un.f4x4
|
||||
, &_render->m_view[ii].un.f4x4
|
||||
, &viewAdjust.un.f4x4
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(&mtxView[0][ii].un.f4x4, &_render->m_view[ii].un.f4x4, sizeof(Matrix4) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint32_t ii = 0; ii < BGFX_CONFIG_MAX_VIEWS; ++ii)
|
||||
{
|
||||
bx::float4x4_mul(&viewProj[ii].un.f4x4, &_render->m_view[ii].un.f4x4, &_render->m_proj[ii].un.f4x4);
|
||||
for (uint32_t eye = 0; eye < uint32_t(hmdEnabled)+1; ++eye)
|
||||
{
|
||||
bx::float4x4_mul(&mtxViewProj[eye][ii].un.f4x4
|
||||
, &mtxView[eye][ii].un.f4x4
|
||||
, &_render->m_proj[eye][ii].un.f4x4
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Matrix4 invView;
|
||||
Matrix4 invProj;
|
||||
Matrix4 invViewProj;
|
||||
uint8_t invViewCached = 0xff;
|
||||
uint8_t invProjCached = 0xff;
|
||||
uint8_t invViewProjCached = 0xff;
|
||||
uint16_t invViewCached = UINT16_MAX;
|
||||
uint16_t invProjCached = UINT16_MAX;
|
||||
uint16_t invViewProjCached = UINT16_MAX;
|
||||
|
||||
uint16_t programIdx = invalidHandle;
|
||||
SortKey key;
|
||||
uint8_t view = 0xff;
|
||||
FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
|
||||
int32_t height = _render->m_resolution.m_height;
|
||||
int32_t height = hmdEnabled
|
||||
? _render->m_hmd.height
|
||||
: _render->m_resolution.m_height
|
||||
;
|
||||
_render->m_resolution.m_height;
|
||||
float alphaRef = 0.0f;
|
||||
uint32_t blendFactor = 0;
|
||||
|
||||
|
@ -4054,16 +4202,33 @@ namespace bgfx
|
|||
{
|
||||
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaBackBufferFbo) );
|
||||
|
||||
for (uint32_t item = 0, numItems = _render->m_num; item < numItems; ++item)
|
||||
bool viewRestart = false;
|
||||
uint8_t eye = 0;
|
||||
uint8_t restartState = 0;
|
||||
Rect rect = _render->m_rect[0];
|
||||
|
||||
int32_t numItems = _render->m_num;
|
||||
for (int32_t item = 0, restartItem = numItems; item < numItems || restartItem < numItems;)
|
||||
{
|
||||
const bool isCompute = key.decode(_render->m_sortKeys[item]);
|
||||
const bool viewChanged = key.m_view != view;
|
||||
const bool viewChanged = 0
|
||||
|| key.m_view != view
|
||||
|| item == numItems
|
||||
;
|
||||
|
||||
const RenderItem& renderItem = _render->m_renderItem[_render->m_sortValues[item] ];
|
||||
++item;
|
||||
|
||||
if (viewChanged)
|
||||
{
|
||||
GL_CHECK(glInsertEventMarker(0, s_viewName[key.m_view]) );
|
||||
if (1 == restartState)
|
||||
{
|
||||
restartState = 2;
|
||||
item = restartItem;
|
||||
restartItem = numItems;
|
||||
view = 0xff;
|
||||
continue;
|
||||
}
|
||||
|
||||
view = key.m_view;
|
||||
programIdx = invalidHandle;
|
||||
|
@ -4071,15 +4236,57 @@ namespace bgfx
|
|||
if (_render->m_fb[view].idx != fbh.idx)
|
||||
{
|
||||
fbh = _render->m_fb[view];
|
||||
height = setFrameBuffer(fbh, _render->m_resolution.m_height);
|
||||
height = hmdEnabled
|
||||
? _render->m_hmd.height
|
||||
: _render->m_resolution.m_height
|
||||
;
|
||||
height = setFrameBuffer(fbh, height);
|
||||
}
|
||||
|
||||
viewRestart = ( (BGFX_VIEW_STEREO == (_render->m_viewFlags[view] & BGFX_VIEW_STEREO) ) );
|
||||
viewRestart &= hmdEnabled;
|
||||
if (viewRestart)
|
||||
{
|
||||
if (0 == restartState)
|
||||
{
|
||||
restartState = 1;
|
||||
restartItem = item - 1;
|
||||
}
|
||||
|
||||
eye = (restartState - 1) & 1;
|
||||
restartState &= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
eye = 0;
|
||||
}
|
||||
|
||||
rect = _render->m_rect[view];
|
||||
if (viewRestart)
|
||||
{
|
||||
char* viewName = s_viewName[view];
|
||||
viewName[3] = eye ? 'R' : 'L';
|
||||
GL_CHECK(glInsertEventMarker(0, viewName) );
|
||||
|
||||
rect.m_x = eye * (rect.m_width+1)/2;
|
||||
rect.m_width /= 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
char* viewName = s_viewName[view];
|
||||
viewName[3] = ' ';
|
||||
GL_CHECK(glInsertEventMarker(0, viewName) );
|
||||
}
|
||||
|
||||
const Rect& rect = _render->m_rect[view];
|
||||
const Rect& scissorRect = _render->m_scissor[view];
|
||||
viewHasScissor = !scissorRect.isZero();
|
||||
viewScissorRect = viewHasScissor ? scissorRect : rect;
|
||||
|
||||
GL_CHECK(glViewport(rect.m_x, height-rect.m_height-rect.m_y, rect.m_width, rect.m_height) );
|
||||
GL_CHECK(glViewport(rect.m_x
|
||||
, height-rect.m_height-rect.m_y
|
||||
, rect.m_width
|
||||
, rect.m_height
|
||||
) );
|
||||
|
||||
Clear& clear = _render->m_clear[view];
|
||||
|
||||
|
@ -4473,28 +4680,28 @@ namespace bgfx
|
|||
{
|
||||
case PredefinedUniform::ViewRect:
|
||||
{
|
||||
float rect[4];
|
||||
rect[0] = _render->m_rect[view].m_x;
|
||||
rect[1] = _render->m_rect[view].m_y;
|
||||
rect[2] = _render->m_rect[view].m_width;
|
||||
rect[3] = _render->m_rect[view].m_height;
|
||||
float frect[4];
|
||||
frect[0] = rect.m_x;
|
||||
frect[1] = rect.m_y;
|
||||
frect[2] = rect.m_width;
|
||||
frect[3] = rect.m_height;
|
||||
|
||||
GL_CHECK(glUniform4fv(predefined.m_loc
|
||||
, 1
|
||||
, &rect[0]
|
||||
, &frect[0]
|
||||
) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::ViewTexel:
|
||||
{
|
||||
float rect[4];
|
||||
rect[0] = 1.0f/float(_render->m_rect[view].m_width);
|
||||
rect[1] = 1.0f/float(_render->m_rect[view].m_height);
|
||||
float frect[4];
|
||||
frect[0] = 1.0f/float(rect.m_width);
|
||||
frect[1] = 1.0f/float(rect.m_height);
|
||||
|
||||
GL_CHECK(glUniform4fv(predefined.m_loc
|
||||
, 1
|
||||
, &rect[0]
|
||||
, &frect[0]
|
||||
) );
|
||||
}
|
||||
break;
|
||||
|
@ -4504,17 +4711,18 @@ namespace bgfx
|
|||
GL_CHECK(glUniformMatrix4fv(predefined.m_loc
|
||||
, 1
|
||||
, GL_FALSE
|
||||
, _render->m_view[view].un.val
|
||||
, mtxView[eye][view].un.val
|
||||
) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::InvView:
|
||||
{
|
||||
if (view != invViewCached)
|
||||
uint16_t viewEye = (view << 1) | eye;
|
||||
if (viewEye != invViewCached)
|
||||
{
|
||||
invViewCached = view;
|
||||
bx::float4x4_inverse(&invView.un.f4x4, &_render->m_view[view].un.f4x4);
|
||||
invViewCached = viewEye;
|
||||
bx::float4x4_inverse(&invView.un.f4x4, &mtxView[eye][view].un.f4x4);
|
||||
}
|
||||
|
||||
GL_CHECK(glUniformMatrix4fv(predefined.m_loc
|
||||
|
@ -4530,17 +4738,18 @@ namespace bgfx
|
|||
GL_CHECK(glUniformMatrix4fv(predefined.m_loc
|
||||
, 1
|
||||
, GL_FALSE
|
||||
, _render->m_proj[view].un.val
|
||||
, _render->m_proj[0][view].un.val
|
||||
) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::InvProj:
|
||||
{
|
||||
if (view != invProjCached)
|
||||
uint16_t viewEye = (view << 1) | eye;
|
||||
if (viewEye != invProjCached)
|
||||
{
|
||||
invProjCached = view;
|
||||
bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[view].un.f4x4);
|
||||
invProjCached = viewEye;
|
||||
bx::float4x4_inverse(&invProj.un.f4x4, &_render->m_proj[eye][view].un.f4x4);
|
||||
}
|
||||
|
||||
GL_CHECK(glUniformMatrix4fv(predefined.m_loc
|
||||
|
@ -4556,17 +4765,18 @@ namespace bgfx
|
|||
GL_CHECK(glUniformMatrix4fv(predefined.m_loc
|
||||
, 1
|
||||
, GL_FALSE
|
||||
, viewProj[view].un.val
|
||||
, mtxViewProj[eye][view].un.val
|
||||
) );
|
||||
}
|
||||
break;
|
||||
|
||||
case PredefinedUniform::InvViewProj:
|
||||
{
|
||||
if (view != invViewProjCached)
|
||||
uint16_t viewEye = (view << 1) | eye;
|
||||
if (viewEye != invViewProjCached)
|
||||
{
|
||||
invViewProjCached = view;
|
||||
bx::float4x4_inverse(&invViewProj.un.f4x4, &viewProj[view].un.f4x4);
|
||||
invViewProjCached = viewEye;
|
||||
bx::float4x4_inverse(&invViewProj.un.f4x4, &mtxViewProj[eye][view].un.f4x4);
|
||||
}
|
||||
|
||||
GL_CHECK(glUniformMatrix4fv(predefined.m_loc
|
||||
|
@ -4592,7 +4802,7 @@ namespace bgfx
|
|||
{
|
||||
Matrix4 modelView;
|
||||
const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
|
||||
bx::float4x4_mul(&modelView.un.f4x4, &model.un.f4x4, &_render->m_view[view].un.f4x4);
|
||||
bx::float4x4_mul(&modelView.un.f4x4, &model.un.f4x4, &mtxView[eye][view].un.f4x4);
|
||||
|
||||
GL_CHECK(glUniformMatrix4fv(predefined.m_loc
|
||||
, 1
|
||||
|
@ -4606,7 +4816,7 @@ namespace bgfx
|
|||
{
|
||||
Matrix4 modelViewProj;
|
||||
const Matrix4& model = _render->m_matrixCache.m_cache[draw.m_matrix];
|
||||
bx::float4x4_mul(&modelViewProj.un.f4x4, &model.un.f4x4, &viewProj[view].un.f4x4);
|
||||
bx::float4x4_mul(&modelViewProj.un.f4x4, &model.un.f4x4, &mtxViewProj[eye][view].un.f4x4);
|
||||
|
||||
GL_CHECK(glUniformMatrix4fv(predefined.m_loc
|
||||
, 1
|
||||
|
@ -4924,11 +5134,15 @@ namespace bgfx
|
|||
, freq/frameTime
|
||||
);
|
||||
|
||||
char hmd[16];
|
||||
bx::snprintf(hmd, BX_COUNTOF(hmd), ", [%c] HMD ", hmdEnabled ? '\xfe' : ' ');
|
||||
|
||||
const uint32_t msaa = (m_resolution.m_flags&BGFX_RESET_MSAA_MASK)>>BGFX_RESET_MSAA_SHIFT;
|
||||
tvm.printf(10, pos++, 0x8e, " Reset flags: [%c] vsync, [%c] MSAAx%d "
|
||||
tvm.printf(10, pos++, 0x8e, " Reset flags: [%c] vsync, [%c] MSAAx%d%s"
|
||||
, !!(m_resolution.m_flags&BGFX_RESET_VSYNC) ? '\xfe' : ' '
|
||||
, 0 != msaa ? '\xfe' : ' '
|
||||
, 1<<msaa
|
||||
, m_ovr.isInitialized() ? hmd : ", no-HMD "
|
||||
);
|
||||
|
||||
double elapsedCpuMs = double(elapsed)*toMs;
|
||||
|
|
|
@ -84,9 +84,10 @@ typedef uint64_t GLuint64;
|
|||
# if BX_PLATFORM_EMSCRIPTEN
|
||||
# include <emscripten/emscripten.h>
|
||||
# endif // BX_PLATFORM_EMSCRIPTEN
|
||||
|
||||
#endif // BGFX_CONFIG_RENDERER_OPENGL
|
||||
|
||||
#include "ovr.h"
|
||||
|
||||
#ifndef GL_LUMINANCE
|
||||
# define GL_LUMINANCE 0x1909
|
||||
#endif // GL_LUMINANCE
|
||||
|
|
Loading…
Add table
Reference in a new issue