Update BGFX (nw)

This commit is contained in:
Miodrag Milanovic 2016-04-07 11:10:57 +02:00
parent dc885b1996
commit 0386367805
28 changed files with 721 additions and 439 deletions

View File

@ -602,6 +602,7 @@
#pragma clang diagnostic ignored "-Wmissing-noreturn" // warning : function xx could be declared with attribute 'noreturn' warning // GetDefaultFontData() asserts which some implementation makes it never return.
#pragma clang diagnostic ignored "-Wdeprecated-declarations"// warning : 'xx' is deprecated: The POSIX name for this item.. // for strdup used in demo code (so user can copy & paste the code)
#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int'
#pragma clang diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used
#endif
#ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used

View File

@ -5,6 +5,8 @@
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
# endif // __clang__
#elif defined(_MSC_VER)
# pragma warning(disable:4244) // warning C4244: '=': conversion from 'int' to 'stbi__uint16', possible loss of data
# pragma warning(disable:4245) // warning C4245: 'argument': conversion from 'int' to 'char', signed/unsigned mismatch
# pragma warning(disable:4312) // warning C4312: 'type cast': conversion from '' to '' of greater size
# pragma warning(disable:4456) // warning C4456: declaration of 'k' hides previous local declaration
# pragma warning(disable:4457) // warning C4457: declaration of 'y' hides function parameter

View File

@ -60,7 +60,7 @@ class ExampleCubes : public entry::AppI
void init(int _argc, char** _argv) BX_OVERRIDE
{
Args args(_argc, _argv);
m_width = 1280;
m_height = 720;
m_debug = BGFX_DEBUG_TEXT;
@ -143,7 +143,7 @@ class ExampleCubes : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
bgfx::setViewTransform(0, view, hmd->eye[0].projection);
bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
// Set view 0 default viewport.
//

View File

@ -467,7 +467,7 @@ class ExampleMetaballs : public entry::AppI
void init(int _argc, char** _argv) BX_OVERRIDE
{
Args args(_argc, _argv);
m_width = 1280;
m_height = 720;
m_debug = BGFX_DEBUG_TEXT;
@ -577,7 +577,7 @@ class ExampleMetaballs : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
bgfx::setViewTransform(0, view, hmd->eye[0].projection);
bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
// Set view 0 default viewport.
//

View File

@ -11,7 +11,7 @@ class ExampleMesh : public entry::AppI
void init(int _argc, char** _argv) BX_OVERRIDE
{
Args args(_argc, _argv);
m_width = 1280;
m_height = 720;
m_debug = BGFX_DEBUG_TEXT;
@ -91,7 +91,7 @@ class ExampleMesh : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
bgfx::setViewTransform(0, view, hmd->eye[0].projection);
bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
// Set view 0 default viewport.
//

View File

@ -160,7 +160,7 @@ class ExampleInstancing : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
bgfx::setViewTransform(0, view, hmd->eye[0].projection);
bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
// Set view 0 default viewport.
//

View File

@ -108,7 +108,7 @@ class ExampleBump : public entry::AppI
void init(int _argc, char** _argv) BX_OVERRIDE
{
Args args(_argc, _argv);
m_width = 1280;
m_height = 720;
m_debug = BGFX_DEBUG_TEXT;
@ -225,7 +225,7 @@ class ExampleBump : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
bgfx::setViewTransform(0, view, hmd->eye[0].projection);
bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
// Set view 0 default viewport.
//

View File

@ -174,7 +174,7 @@ class ExampleLod : public entry::AppI
{
float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
bgfx::setViewTransform(0, view, hmd->eye[0].projection);
bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
// Set view 0 default viewport.
//

View File

@ -305,7 +305,7 @@ int _main_(int _argc, char** _argv)
float tmp[16];
bx::mtxMul(tmp, view, viewHead);
bgfx::setViewTransform(0, tmp, hmd->eye[0].projection);
bgfx::setViewTransform(0, tmp, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
// Set view 0 default viewport.
//

View File

@ -65,9 +65,6 @@ class DebugDrawApp : public entry::AppI
{
if (!entry::processEvents(m_width, m_height, m_debug, m_reset, &m_mouseState) )
{
// Set view 0 default viewport.
bgfx::setViewRect(0, 0, 0, m_width, m_height);
int64_t now = bx::getHPCounter() - m_timeOffset;
static int64_t last = now;
const int64_t frameTime = now - last;
@ -89,9 +86,24 @@ class DebugDrawApp : public entry::AppI
cameraGetViewMtx(view);
float proj[16];
bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f);
bgfx::setViewTransform(0, view, proj);
// Set view and projection matrix for view 0.
const bgfx::HMD* hmd = bgfx::getHMD();
if (NULL != hmd && 0 != (hmd->flags & BGFX_HMD_RENDERING) )
{
float eye[3];
cameraGetPosition(eye);
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye);
bgfx::setViewTransform(0, view, hmd->eye[0].projection, BGFX_VIEW_STEREO, hmd->eye[1].projection);
bgfx::setViewRect(0, 0, 0, hmd->width, hmd->height);
}
else
{
bx::mtxProj(proj, 60.0f, float(m_width)/float(m_height), 0.1f, 100.0f);
bgfx::setViewTransform(0, view, proj);
bgfx::setViewRect(0, 0, 0, m_width, m_height);
}
float zero[3] = {};
@ -174,6 +186,21 @@ class DebugDrawApp : public entry::AppI
ddDrawCircle(Axis::Z, -8.0f, 0.0f, 0.0f, 1.25f, 2.0f);
ddPop();
ddPush();
ddSetLod(UINT8_MAX);
{
float from[3] = { -11.0f, 4.0f, 0.0f };
float to[3] = { -13.0f, 6.0f, 1.0f };
ddDrawCone(from, to, 1.0f );
}
{
float from[3] = { -9.0f, 2.0f, -1.0f };
float to[3] = { -11.0f, 4.0f, 0.0f };
ddDrawCylinder(from, to, 0.5f );
}
ddPop();
ddDrawOrb(-11.0f, 0.0f, 0.0f, 1.0f);
ddEnd();

View File

@ -1018,6 +1018,132 @@ struct DebugDraw
close();
}
void drawCone(const float* _from, const float* _to, float _radius, float _weight = 0.0f)
{
const Attrib& attrib = m_attrib[m_stack];
const uint32_t num = getCircleLod(attrib.m_lod);
const float step = bx::pi * 2.0f / num;
_weight = bx::fclamp(_weight, 0.0f, 2.0f);
float pos[3];
float tmp0[3];
float tmp1[3];
bx::vec3Sub(tmp0, _from, _to);
Plane plane;
plane.m_dist = 0.0f;
bx::vec3Norm(plane.m_normal, tmp0);
float udir[3];
float vdir[3];
calcPlaneUv(plane, udir, vdir);
float xy0[2];
float xy1[2];
circle(xy0, 0.0f);
squircle(xy1, 0.0f);
bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius);
bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius);
bx::vec3Add(tmp1, pos, tmp0);
bx::vec3Add(pos, tmp1, _from);
moveTo(pos);
for (uint32_t ii = 1; ii < num; ++ii)
{
float angle = step * ii;
circle(xy0, angle);
squircle(xy1, angle);
bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius);
bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius);
bx::vec3Add(tmp1, pos, tmp0);
bx::vec3Add(pos, tmp1, _from);
lineTo(pos);
}
close();
for (uint32_t ii = 0; ii < num; ++ii)
{
float angle = step * ii;
circle(xy0, angle);
squircle(xy1, angle);
bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius);
bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius);
bx::vec3Add(tmp1, pos, tmp0);
bx::vec3Add(pos, tmp1, _from);
moveTo(pos);
lineTo(_to);
}
}
void drawCone(const void* _from, const void* _to, float _radius, float _weight = 0.0f)
{
drawCone( (const float*)_from, (const float*)_to, _radius, _weight);
}
void drawCylinder(const float* _from, const float* _to, float _radius, float _weight = 0.0f)
{
const Attrib& attrib = m_attrib[m_stack];
const uint32_t num = getCircleLod(attrib.m_lod);
const float step = bx::pi * 2.0f / num;
_weight = bx::fclamp(_weight, 0.0f, 2.0f);
float pos[3];
float tmp0[3];
float tmp1[3];
bx::vec3Sub(tmp0, _from, _to);
Plane plane;
plane.m_dist = 0.0f;
bx::vec3Norm(plane.m_normal, tmp0);
float udir[3];
float vdir[3];
calcPlaneUv(plane, udir, vdir);
float xy0[2];
float xy1[2];
circle(xy0, 0.0f);
squircle(xy1, 0.0f);
float pos1[3];
bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius);
bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius);
bx::vec3Add(tmp1, pos, tmp0);
bx::vec3Add(pos, tmp1, _from);
bx::vec3Add(pos1, tmp1, _to);
for (uint32_t ii = 1; ii < num+1; ++ii)
{
float angle = step * ii;
circle(xy0, angle);
squircle(xy1, angle);
moveTo(pos); lineTo(pos1);
moveTo(pos);
bx::vec3Mul(pos, udir, bx::flerp(xy0[0], xy1[0], _weight)*_radius);
bx::vec3Mul(tmp0, vdir, bx::flerp(xy0[1], xy1[1], _weight)*_radius);
bx::vec3Add(tmp1, pos, tmp0);
bx::vec3Add(pos, tmp1, _from);
lineTo(pos);
moveTo(pos1);
bx::vec3Add(pos1, tmp1, _to);
lineTo(pos1);
}
}
void drawCylinder(const void* _from, const void* _to, float _radius, float _weight = 0.0f)
{
drawCylinder( (const float*)_from, (const float*)_to, _radius, _weight);
}
void drawAxis(float _x, float _y, float _z, float _len, Axis::Enum _highlight)
{
push();
@ -1271,18 +1397,19 @@ private:
bgfx::allocTransientIndexBuffer(&tib, m_indexPos);
memcpy(tib.data, m_indices, m_indexPos * sizeof(uint16_t) );
const Attrib& attrib = m_attrib[m_stack];
bgfx::setVertexBuffer(&tvb);
bgfx::setIndexBuffer(&tib);
bgfx::setState(0
| BGFX_STATE_RGB_WRITE
| BGFX_STATE_PT_LINES
| (m_depthTestLess ? BGFX_STATE_DEPTH_TEST_LEQUAL : BGFX_STATE_DEPTH_TEST_GEQUAL)
| BGFX_STATE_DEPTH_WRITE
| attrib.m_state
| BGFX_STATE_LINEAA
| BGFX_STATE_BLEND_ALPHA
);
bgfx::setTransform(m_mtx);
bgfx::ProgramHandle program = m_program[m_attrib[m_stack].m_stipple ? 1 : 0];
bgfx::ProgramHandle program = m_program[attrib.m_stipple ? 1 : 0];
bgfx::submit(m_viewId, program);
}
@ -1481,6 +1608,16 @@ void ddDrawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius,
s_dd.drawCircle(_axis, _x, _y, _z, _radius, _weight);
}
void ddDrawCone(const void* _from, const void* _to, float _radius, float _weight)
{
s_dd.drawCone(_from, _to, _radius, _weight);
}
void ddDrawCylinder(const void* _from, const void* _to, float _radius, float _weight)
{
s_dd.drawCylinder(_from, _to, _radius, _weight);
}
void ddDrawAxis(float _x, float _y, float _z, float _len, Axis::Enum _hightlight)
{
s_dd.drawAxis(_x, _y, _z, _len, _hightlight);

View File

@ -102,6 +102,12 @@ void ddDrawCircle(const void* _normal, const void* _center, float _radius, float
///
void ddDrawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _weight = 0.0f);
///
void ddDrawCone(const void* _from, const void* _to, float _radius, float _weight = 0.0f);
///
void ddDrawCylinder(const void* _from, const void* _to, float _radius, float _weight = 0.0f);
///
void ddDrawAxis(float _x, float _y, float _z, float _len = 1.0f, Axis::Enum _highlight = Axis::Count);

View File

@ -2165,7 +2165,8 @@ namespace bgfx
///
/// @param[in] _handle Uniform.
/// @param[in] _value Pointer to uniform data.
/// @param[in] _num Number of elements.
/// @param[in] _num Number of elements. Passing `UINT16_MAX` will
/// use the _num passed on uniform creation.
///
/// @attention C99 equivalent is `bgfx_set_uniform`.
///

View File

@ -51,11 +51,23 @@ function bgfxProject(_name, _kind, _defines)
if _OPTIONS["with-ovr"] then
defines {
-- "BGFX_CONFIG_MULTITHREADED=0",
"BGFX_CONFIG_USE_OVR=1",
}
includedirs {
"$(OVR_DIR)/LibOVR/Include",
}
configuration { "x32" }
libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Windows/Win32/Release", _ACTION) }
configuration { "x64" }
libdirs { path.join("$(OVR_DIR)/LibOVR/Lib/Windows/x64/Release", _ACTION) }
configuration { "x32 or x64" }
links { "libovr" }
configuration {}
end
configuration { "Debug" }

View File

@ -1431,16 +1431,16 @@ namespace bgfx
m_indexBufferHandle.free(_frame->m_freeIndexBufferHandle[ii].idx);
}
for (uint16_t ii = 0, num = _frame->m_numFreeVertexDeclHandles; ii < num; ++ii)
{
m_vertexDeclHandle.free(_frame->m_freeVertexDeclHandle[ii].idx);
}
for (uint16_t ii = 0, num = _frame->m_numFreeVertexBufferHandles; ii < num; ++ii)
{
destroyVertexBufferInternal(_frame->m_freeVertexBufferHandle[ii]);
}
for (uint16_t ii = 0, num = _frame->m_numFreeVertexDeclHandles; ii < num; ++ii)
{
m_vertexDeclHandle.free(_frame->m_freeVertexDeclHandle[ii].idx);
}
for (uint16_t ii = 0, num = _frame->m_numFreeShaderHandles; ii < num; ++ii)
{
m_shaderHandle.free(_frame->m_freeShaderHandle[ii].idx);

View File

@ -3617,7 +3617,7 @@ namespace bgfx
{
BGFX_CHECK_HANDLE("setUniform", m_uniformHandle, _handle);
UniformRef& uniform = m_uniformRef[_handle.idx];
BX_CHECK(uniform.m_num >= _num, "Truncated uniform update. %d (max: %d)", _num, uniform.m_num);
BX_CHECK(_num == UINT16_MAX || uniform.m_num >= _num, "Truncated uniform update. %d (max: %d)", _num, uniform.m_num);
if (BX_ENABLED(BGFX_CONFIG_DEBUG_UNIFORM) )
{
BX_CHECK(m_uniformSet.end() == m_uniformSet.find(_handle.idx)

View File

@ -394,10 +394,39 @@ vec4 mod(vec4 _a, vec4 _b) { return _a - _b * floor(_a / _b); }
# define USAMPLER2D(_name, _reg) uniform usampler2D _name
# define ISAMPLER3D(_name, _reg) uniform isampler3D _name
# define USAMPLER3D(_name, _reg) uniform usampler3D _name
ivec4 texture2D(isampler2D _sampler, vec2 _coord) { return texture(_sampler, _coord); }
uvec4 texture2D(usampler2D _sampler, vec2 _coord) { return texture(_sampler, _coord); }
ivec4 texture3D(isampler3D _sampler, vec3 _coord) { return texture(_sampler, _coord); }
uvec4 texture3D(usampler3D _sampler, vec3 _coord) { return texture(_sampler, _coord); }
vec4 bgfxTexture2D(sampler2D _sampler, vec2 _coord)
{
return texture(_sampler, _coord);
}
ivec4 bgfxTexture2D(isampler2D _sampler, vec2 _coord)
{
return texture(_sampler, _coord);
}
uvec4 bgfxTexture2D(usampler2D _sampler, vec2 _coord)
{
return texture(_sampler, _coord);
}
vec4 bgfxTexture3D(sampler3D _sampler, vec3 _coord)
{
return texture(_sampler, _coord);
}
ivec4 bgfxTexture3D(isampler3D _sampler, vec3 _coord)
{
return texture(_sampler, _coord);
}
uvec4 bgfxTexture3D(usampler3D _sampler, vec3 _coord)
{
return texture(_sampler, _coord);
}
# define texture2D(_sampler, _coord) bgfxTexture2D(_sampler, _coord)
# define texture3D(_sampler, _coord) bgfxTexture3D(_sampler, _coord)
# endif // BGFX_SHADER_LANGUAGE_GLSL >= 130
vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); }

View File

@ -9,11 +9,20 @@
namespace bgfx
{
#define _OVR_CHECK(_call) \
BX_MACRO_BLOCK_BEGIN \
ovrResult __result__ = _call; \
BX_CHECK(OVR_SUCCESS(__result__), #_call " FAILED %d", __result__); \
BX_MACRO_BLOCK_END
#if BGFX_CONFIG_DEBUG
# define OVR_CHECK(_call) _OVR_CHECK(_call)
#endif // BGFX_CONFIG_DEBUG
OVR::OVR()
: m_hmd(NULL)
, m_isenabled(false)
, m_enabled(false)
, m_mirror(NULL)
, m_hmdFrameReady(-1)
, m_frameIndex(0)
, m_sensorSampleTime(0)
{
@ -27,20 +36,19 @@ namespace bgfx
void OVR::init()
{
ovrResult initialized = ovr_Initialize(NULL);
ovrGraphicsLuid luid;
ovrResult result = ovr_Initialize(NULL);
BX_WARN(initialized == ovrSuccess, "Unable to create OVR device.");
if (initialized != ovrSuccess)
if (result != ovrSuccess)
{
BX_TRACE("Unable to create OVR device.");
return;
}
initialized = ovr_Create(&m_hmd, &luid);
if (initialized != ovrSuccess)
ovrGraphicsLuid luid;
result = ovr_Create(&m_hmd, &luid);
if (result != ovrSuccess)
{
BX_WARN(initialized == ovrSuccess, "Unable to create OVR device.");
BX_TRACE("Unable to create OVR device.");
return;
}
@ -61,21 +69,21 @@ namespace bgfx
void OVR::shutdown()
{
BX_CHECK(!m_isenabled, "HMD not disabled.");
BX_CHECK(!m_enabled, "HMD not disabled.");
for (int i = 0; i < 2; i++)
for (uint32_t ii = 0; ii < 2; ++ii)
{
if (m_eyeBuffers[i])
if (NULL != m_eyeBuffers[ii])
{
m_eyeBuffers[i]->destroy(m_hmd);
BX_DELETE(g_allocator, m_eyeBuffers[i]);
m_eyeBuffers[ii]->destroy(m_hmd);
m_eyeBuffers[ii] = NULL;
}
}
if (m_mirror)
if (NULL != m_mirror)
{
m_mirror->destroy(m_hmd);
BX_DELETE(g_allocator, m_mirror);
m_mirror = NULL;
}
ovr_Destroy(m_hmd);
@ -93,7 +101,7 @@ namespace bgfx
void OVR::renderEyeStart(uint8_t _eye)
{
m_eyeBuffers[_eye]->onRender(m_hmd);
m_eyeBuffers[_eye]->render(m_hmd);
}
bool OVR::postReset()
@ -103,37 +111,28 @@ namespace bgfx
return false;
}
for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
for (uint32_t ii = 0; ii < 2; ++ii)
{
m_erd[eyeIdx] = ovr_GetRenderDesc(m_hmd, (ovrEyeType)eyeIdx, m_hmdDesc.DefaultEyeFov[eyeIdx]);
m_erd[ii] = ovr_GetRenderDesc(m_hmd, ovrEyeType(ii), m_hmdDesc.DefaultEyeFov[ii]);
}
m_isenabled = true;
m_enabled = true;
return true;
}
void OVR::preReset()
{
if (m_isenabled)
if (m_enabled)
{
// on window resize this will recreate the mirror texture in ovrPostReset
m_mirror->destroy(m_hmd);
BX_DELETE(g_allocator, m_mirror);
m_mirror = NULL;
m_isenabled = false;
m_enabled = false;
}
}
void OVR::commitEye(uint8_t _eye)
{
if (m_isenabled)
{
m_hmdFrameReady = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[_eye]->m_swapTextureChain);
}
}
bool OVR::swap(HMD& _hmd, bool originBottomLeft)
OVR::Enum OVR::swap(HMD& _hmd, bool originBottomLeft)
{
_hmd.flags = BGFX_HMD_NONE;
@ -144,9 +143,20 @@ namespace bgfx
_hmd.deviceHeight = m_hmdDesc.Resolution.h;
}
if (!m_isenabled || !OVR_SUCCESS(m_hmdFrameReady))
if (!m_enabled)
{
return false;
return NotEnabled;
}
ovrResult result;
for (uint32_t ii = 0; ii < 2; ++ii)
{
result = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[ii]->m_textureSwapChain);
if (!OVR_SUCCESS(result) )
{
return DeviceLost;
}
}
_hmd.flags |= BGFX_HMD_RENDERING;
@ -162,22 +172,26 @@ namespace bgfx
eyeLayer.Header.Type = ovrLayerType_EyeFov;
eyeLayer.Header.Flags = originBottomLeft ? ovrLayerFlag_TextureOriginAtBottomLeft : 0;
for (int eye = 0; eye < ovrEye_Count; eye++)
for (uint32_t ii = 0; ii < 2; ++ii)
{
eyeLayer.ColorTexture[eye] = m_eyeBuffers[eye]->m_swapTextureChain;
eyeLayer.Viewport[eye].Pos.x = 0;
eyeLayer.Viewport[eye].Pos.y = 0;
eyeLayer.Viewport[eye].Size.w = m_eyeBuffers[eye]->m_eyeTextureSize.w;
eyeLayer.Viewport[eye].Size.h = m_eyeBuffers[eye]->m_eyeTextureSize.h;
eyeLayer.Fov[eye] = m_hmdDesc.DefaultEyeFov[eye];
eyeLayer.RenderPose[eye] = m_pose[eye];
eyeLayer.SensorSampleTime = m_sensorSampleTime;
eyeLayer.ColorTexture[ii] = m_eyeBuffers[ii]->m_textureSwapChain;
eyeLayer.Viewport[ii].Pos.x = 0;
eyeLayer.Viewport[ii].Pos.y = 0;
eyeLayer.Viewport[ii].Size.w = m_eyeBuffers[ii]->m_eyeTextureSize.w;
eyeLayer.Viewport[ii].Size.h = m_eyeBuffers[ii]->m_eyeTextureSize.h;
eyeLayer.Fov[ii] = m_hmdDesc.DefaultEyeFov[ii];
eyeLayer.RenderPose[ii] = m_pose[ii];
eyeLayer.SensorSampleTime = m_sensorSampleTime;
}
// append all the layers to global list
ovrLayerHeader* layerList = &eyeLayer.Header;
ovr_SubmitFrame(m_hmd, m_frameIndex, NULL, &layerList, 1);
result = ovr_SubmitFrame(m_hmd, m_frameIndex, NULL, &layerList, 1);
if (!OVR_SUCCESS(result) )
{
return DeviceLost;
}
// perform mirror texture blit right after the entire frame is submitted to HMD
m_mirror->blit(m_hmd);
@ -189,14 +203,14 @@ namespace bgfx
getEyePose(_hmd);
return true;
return Success;
}
void OVR::recenter()
{
if (NULL != m_hmd)
{
ovr_RecenterTrackingOrigin(m_hmd);
OVR_CHECK(ovr_RecenterTrackingOrigin(m_hmd) );
}
}
@ -204,7 +218,7 @@ namespace bgfx
{
if (NULL != m_hmd)
{
for (int ii = 0; ii < 2; ++ii)
for (uint32_t ii = 0; ii < 2; ++ii)
{
const ovrPosef& pose = m_pose[ii];
HMD::Eye& eye = _hmd.eye[ii];
@ -223,9 +237,9 @@ namespace bgfx
eye.fov[3] = erd.Fov.RightTan;
ovrMatrix4f eyeProj = ovrMatrix4f_Projection(m_erd[ii].Fov, 0.01f, 1000.0f, ovrProjection_LeftHanded);
for (int jj = 0; jj < 4; ++jj)
for (uint32_t jj = 0; jj < 4; ++jj)
{
for (int kk = 0; kk < 4; ++kk)
for (uint32_t kk = 0; kk < 4; ++kk)
{
eye.projection[4 * jj + kk] = eyeProj.M[kk][jj];
}

View File

@ -31,27 +31,37 @@ namespace bgfx
struct OVRBufferI
{
virtual ~OVRBufferI() {};
virtual void onRender(const ovrSession &session) = 0;
virtual void destroy(const ovrSession &session) = 0;
virtual void create(const ovrSession& _session, int _eyeIdx) = 0;
virtual void destroy(const ovrSession& _session) = 0;
virtual void render(const ovrSession& _session) = 0;
ovrSizei m_eyeTextureSize;
ovrTextureSwapChain m_swapTextureChain;
ovrSizei m_eyeTextureSize;
ovrTextureSwapChain m_textureSwapChain;
};
// mirrored window output
struct OVRMirrorI
{
virtual ~OVRMirrorI() {};
virtual void init(const ovrSession &session, int windowWidth, int windowHeight) = 0;
virtual void destroy(const ovrSession &session) = 0;
virtual void blit(const ovrSession &session) = 0;
virtual void create(const ovrSession& _session, int windowWidth, int windowHeight) = 0;
virtual void destroy(const ovrSession& _session) = 0;
virtual void blit(const ovrSession& _session) = 0;
ovrMirrorTexture m_mirrorTexture;
ovrMirrorTextureDesc m_mirrorDesc;
ovrMirrorTextureDesc m_mirrorTextureDesc;
};
struct OVR
{
enum Enum
{
NotEnabled,
DeviceLost,
Success,
Count
};
OVR();
~OVR();
@ -62,7 +72,7 @@ namespace bgfx
bool isEnabled() const
{
return m_isenabled;
return m_enabled;
}
void init();
@ -72,8 +82,7 @@ namespace bgfx
void renderEyeStart(uint8_t _eye);
bool postReset();
void preReset();
void commitEye(uint8_t _eye);
bool swap(HMD& _hmd, bool originBottomLeft);
Enum swap(HMD& _hmd, bool originBottomLeft);
void recenter();
void getEyePose(HMD& _hmd);
@ -84,12 +93,11 @@ namespace bgfx
ovrPosef m_pose[2];
ovrVector3f m_hmdToEyeOffset[2];
ovrSizei m_hmdSize;
ovrResult m_hmdFrameReady;
OVRBufferI *m_eyeBuffers[2];
OVRMirrorI *m_mirror;
long long m_frameIndex;
uint64_t m_frameIndex;
double m_sensorSampleTime;
bool m_isenabled;
bool m_enabled;
};
} // namespace bgfx
@ -100,6 +108,15 @@ namespace bgfx
{
struct OVR
{
enum Enum
{
NotEnabled,
DeviceLost,
Success,
Count
};
OVR()
{
}
@ -139,19 +156,15 @@ namespace bgfx
_viewport->m_height = 0;
}
void commitEye(uint8_t /*_eye*/)
{
}
void renderEyeStart(uint8_t /*_eye*/)
{
}
bool swap(HMD& _hmd, bool /*originBottomLeft*/)
Enum swap(HMD& _hmd, bool /*originBottomLeft*/)
{
_hmd.flags = BGFX_HMD_NONE;
getEyePose(_hmd);
return false;
return NotEnabled;
}
void recenter()

View File

@ -252,24 +252,12 @@ namespace bgfx
const uint16_t minBlockX = blockInfo.minBlockX;
const uint16_t minBlockY = blockInfo.minBlockY;
_width = bx::uint16_max(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth)*blockWidth);
_height = bx::uint16_max(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
_depth = bx::uint16_max(1, _depth);
_width = bx::uint16_max(blockWidth * minBlockX, ( (_width + blockWidth - 1) / blockWidth)*blockWidth);
_height = bx::uint16_max(blockHeight * minBlockY, ( (_height + blockHeight - 1) / blockHeight)*blockHeight);
_depth = bx::uint16_max(1, _depth);
uint8_t numMips = 0;
for (uint32_t width = _width, height = _height, depth = _depth
; blockWidth < width || blockHeight < height || 1 < depth
; ++numMips)
{
width = bx::uint32_max(blockWidth * minBlockX, ( (width + blockWidth - 1) / blockWidth )*blockWidth);
height = bx::uint32_max(blockHeight * minBlockY, ( (height + blockHeight - 1) / blockHeight)*blockHeight);
depth = bx::uint32_max(1, depth);
width >>= 1;
height >>= 1;
depth >>= 1;
}
uint32_t max = bx::uint32_max(_width, bx::uint32_max(_height, _depth) );
uint8_t numMips = uint8_t(bx::flog2(float(max) ) );
return numMips;
}

View File

@ -601,170 +601,6 @@ namespace bgfx { namespace d3d11
static PFN_GET_DEBUG_INTERFACE1 DXGIGetDebugInterface1;
#endif // USE_D3D11_DYNAMIC_LIB
#if BGFX_CONFIG_USE_OVR
#include <tinystl/vector.h>
// Oculus Rift eye buffer
struct OVRBufferDX11 : public OVRBufferI
{
OVRBufferDX11(const ovrSession& session, int eyeIdx, ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dCtx)
{
m_d3dDevice = d3dDevice;
m_d3dContext = d3dCtx;
ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session);
m_eyeTextureSize = ovr_GetFovTextureSize(session, (ovrEyeType)eyeIdx, hmdDesc.DefaultEyeFov[eyeIdx], 1.0f);
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.Width = m_eyeTextureSize.w;
desc.Height = m_eyeTextureSize.h;
desc.MipLevels = 1;
desc.SampleCount = 1;
desc.MiscFlags = ovrTextureMisc_DX_Typeless;
desc.BindFlags = ovrTextureBind_DX_RenderTarget;
desc.StaticImage = ovrFalse;
ovrResult result = ovr_CreateTextureSwapChainDX(session, d3dDevice, &desc, &m_swapTextureChain);
if (!OVR_SUCCESS(result))
{
BX_CHECK(false, "Could not create D3D11 OVR swap texture");
}
int textureCount = 0;
ovr_GetTextureSwapChainLength(session, m_swapTextureChain, &textureCount);
for (int i = 0; i < textureCount; ++i)
{
ID3D11Texture2D* tex = NULL;
ovr_GetTextureSwapChainBufferDX(session, m_swapTextureChain, i, IID_PPV_ARGS(&tex));
D3D11_RENDER_TARGET_VIEW_DESC rtvd = {};
rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
ID3D11RenderTargetView* rtv;
DX_CHECK(d3dDevice->CreateRenderTargetView(tex, &rtvd, &rtv));
m_eyeRtv.push_back(rtv);
tex->Release();
}
// setup depth buffer
D3D11_TEXTURE2D_DESC dbDesc;
dbDesc.Width = m_eyeTextureSize.w;
dbDesc.Height = m_eyeTextureSize.h;
dbDesc.MipLevels = 1;
dbDesc.ArraySize = 1;
dbDesc.Format = DXGI_FORMAT_D32_FLOAT;
dbDesc.SampleDesc.Count = 1;
dbDesc.SampleDesc.Quality = 0;
dbDesc.Usage = D3D11_USAGE_DEFAULT;
dbDesc.CPUAccessFlags = 0;
dbDesc.MiscFlags = 0;
dbDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
ID3D11Texture2D* tex;
DX_CHECK(d3dDevice->CreateTexture2D(&dbDesc, NULL, &tex));
DX_CHECK(d3dDevice->CreateDepthStencilView(tex, NULL, &m_depthBuffer));
tex->Release();
}
void onRender(const ovrSession& session)
{
// Clear and set up rendertarget
int texIndex = 0;
ovr_GetTextureSwapChainCurrentIndex(session, m_swapTextureChain, &texIndex);
float black[] = { 0.f, 0.f, 0.f, 0.f }; // Important that alpha=0, if want pixels to be transparent, for manual layers
m_d3dContext->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer);
m_d3dContext->ClearRenderTargetView(m_eyeRtv[texIndex], black);
m_d3dContext->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
D3D11_VIEWPORT D3Dvp;
D3Dvp.TopLeftX = 0;
D3Dvp.TopLeftY = 0;
D3Dvp.Width = (FLOAT)m_eyeTextureSize.w;
D3Dvp.Height = (FLOAT)m_eyeTextureSize.h;
D3Dvp.MinDepth = 0;
D3Dvp.MaxDepth = 1;
m_d3dContext->RSSetViewports(1, &D3Dvp);
}
void destroy(const ovrSession& session)
{
for (size_t i = 0; i < m_eyeRtv.size(); ++i)
{
m_eyeRtv[i]->Release();
}
ovr_DestroyTextureSwapChain(session, m_swapTextureChain);
m_depthBuffer->Release();
}
ID3D11Device* m_d3dDevice;
ID3D11DeviceContext* m_d3dContext;
stl::vector<ID3D11RenderTargetView *> m_eyeRtv;
ID3D11DepthStencilView* m_depthBuffer;
};
// Oculus Rift mirror
struct OVRMirrorDX11 : public OVRMirrorI
{
OVRMirrorDX11(ID3D11Device* d3dDevice,
ID3D11DeviceContext* d3dCtx,
IDXGISwapChain* d3dSc) : m_d3dDevice(d3dDevice)
, m_d3dContext(d3dCtx)
, m_d3dSwapChain(d3dSc)
{
}
void init(const ovrSession& session, int windowWidth, int windowHeight)
{
m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
m_mirrorDesc.Width = windowWidth;
m_mirrorDesc.Height = windowHeight;
ovrResult result = ovr_CreateMirrorTextureDX(session, m_d3dDevice, &m_mirrorDesc, &m_mirrorTexture);
if (!OVR_SUCCESS(result))
{
BX_CHECK(false, "Could not create D3D11 OVR mirror texture");
}
}
void destroy(const ovrSession& session)
{
if (!m_mirrorTexture)
return;
ovr_DestroyMirrorTexture(session, m_mirrorTexture);
m_mirrorTexture = NULL;
}
void blit(const ovrSession& session)
{
if (!m_mirrorTexture)
return;
ID3D11Texture2D* tex = NULL;
ovr_GetMirrorTextureBufferDX(session, m_mirrorTexture, IID_PPV_ARGS(&tex));
ID3D11Texture2D* backBuffer;
DX_CHECK(m_d3dSwapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer));
m_d3dContext->CopyResource(backBuffer, tex);
DX_CHECK(m_d3dSwapChain->Present(0, 0));
tex->Release();
backBuffer->Release();
}
ID3D11Device* m_d3dDevice;
ID3D11DeviceContext* m_d3dContext;
IDXGISwapChain* m_d3dSwapChain;
};
#endif // BGFX_CONFIG_USE_OVR
struct RendererContextD3D11 : public RendererContextI
{
RendererContextD3D11()
@ -1178,6 +1014,13 @@ namespace bgfx { namespace d3d11
}
}
if (NULL != m_renderdocdll)
{
// RenderDoc doesn't support ID3D11Device3 yet:
// https://github.com/baldurk/renderdoc/issues/235
m_deviceInterfaceVersion = bx::uint32_min(m_deviceInterfaceVersion, 1);
}
IDXGIDevice* device = NULL;
IDXGIAdapter* adapter = NULL;
hr = E_FAIL;
@ -1386,7 +1229,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
}
{
UniformHandle handle = BGFX_INVALID_HANDLE;
for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
{
@ -2350,9 +2192,18 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (SUCCEEDED(hr) )
{
if (!m_ovr.swap(_hmd, false) )
switch (m_ovr.swap(_hmd, false) )
{
case OVR::NotEnabled:
hr = m_swapChain->Present(syncInterval, 0);
break;
case OVR::DeviceLost:
ovrPreReset();
break;
default:
break;
}
}
@ -3243,20 +3094,21 @@ BX_PRAGMA_DIAGNOSTIC_POP();
#if BGFX_CONFIG_USE_OVR
if (m_resolution.m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
{
if (m_ovr.postReset())
if (m_ovr.postReset() )
{
for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
for (uint32_t ii = 0; ii < 2; ++ii)
{
// eye buffers need to be initialized only once during application lifetime
if (!m_ovr.m_eyeBuffers[eyeIdx])
if (NULL == m_ovr.m_eyeBuffers[ii])
{
m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferDX11(m_ovr.m_hmd, eyeIdx, m_device, m_deviceCtx));
m_ovr.m_eyeBuffers[ii] = &m_ovrBuffers[ii];
m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii);
}
}
// recreate mirror texture
m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorDX11(m_device, m_deviceCtx, m_swapChain));
m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
m_ovr.m_mirror = &m_ovrMirror;
m_ovr.m_mirror->create(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@ -3657,6 +3509,10 @@ BX_PRAGMA_DIAGNOSTIC_POP();
bool m_timerQuerySupport;
OVR m_ovr;
#if BGFX_CONFIG_USE_OVR
OVRMirrorD3D11 m_ovrMirror;
OVRBufferD3D11 m_ovrBuffers[2];
#endif // BGFX_CONFIG_USE_OVR
};
static RendererContextD3D11* s_renderD3D11;
@ -3709,6 +3565,140 @@ BX_PRAGMA_DIAGNOSTIC_POP();
agsDriverExtensions_MultiDrawIndexedInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride);
}
#if BGFX_CONFIG_USE_OVR
void OVRBufferD3D11::create(const ovrSession& _session, int _eyeIdx)
{
ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session);
m_eyeTextureSize = ovr_GetFovTextureSize(_session, (ovrEyeType)_eyeIdx, hmdDesc.DefaultEyeFov[_eyeIdx], 1.0f);
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.Width = m_eyeTextureSize.w;
desc.Height = m_eyeTextureSize.h;
desc.MipLevels = 1;
desc.SampleCount = 1;
desc.MiscFlags = ovrTextureMisc_DX_Typeless;
desc.BindFlags = ovrTextureBind_DX_RenderTarget;
desc.StaticImage = ovrFalse;
ID3D11Device* device = s_renderD3D11->m_device;
ovrResult result = ovr_CreateTextureSwapChainDX(_session, device, &desc, &m_textureSwapChain);
if (!OVR_SUCCESS(result) )
{
BX_CHECK(false, "Could not create D3D11 OVR swap texture");
}
memset(m_eyeRtv, 0, sizeof(m_eyeRtv) );
int textureCount = 0;
ovr_GetTextureSwapChainLength(_session, m_textureSwapChain, &textureCount);
for (int ii = 0; ii < textureCount; ++ii)
{
ID3D11Texture2D* tex = NULL;
ovr_GetTextureSwapChainBufferDX(_session, m_textureSwapChain, ii, IID_PPV_ARGS(&tex) );
D3D11_RENDER_TARGET_VIEW_DESC rtvd = {};
rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
ID3D11RenderTargetView* rtv;
DX_CHECK(device->CreateRenderTargetView(tex, &rtvd, &rtv) );
m_eyeRtv[ii] = rtv;
DX_RELEASE(tex, 1);
}
// setup depth buffer
D3D11_TEXTURE2D_DESC dbDesc;
dbDesc.Width = m_eyeTextureSize.w;
dbDesc.Height = m_eyeTextureSize.h;
dbDesc.MipLevels = 1;
dbDesc.ArraySize = 1;
dbDesc.Format = DXGI_FORMAT_D32_FLOAT;
dbDesc.SampleDesc.Count = 1;
dbDesc.SampleDesc.Quality = 0;
dbDesc.Usage = D3D11_USAGE_DEFAULT;
dbDesc.CPUAccessFlags = 0;
dbDesc.MiscFlags = 0;
dbDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
ID3D11Texture2D* tex;
DX_CHECK(device->CreateTexture2D(&dbDesc, NULL, &tex) );
DX_CHECK(device->CreateDepthStencilView(tex, NULL, &m_depthBuffer) );
DX_RELEASE(tex, 0);
}
void OVRBufferD3D11::render(const ovrSession& _session)
{
// Clear and set up rendertarget
int texIndex = 0;
ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &texIndex);
ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; // Important that alpha=0, if want pixels to be transparent, for manual layers
deviceCtx->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer);
deviceCtx->ClearRenderTargetView(m_eyeRtv[texIndex], black);
deviceCtx->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
D3D11_VIEWPORT D3Dvp;
D3Dvp.TopLeftX = 0;
D3Dvp.TopLeftY = 0;
D3Dvp.Width = (FLOAT)m_eyeTextureSize.w;
D3Dvp.Height = (FLOAT)m_eyeTextureSize.h;
D3Dvp.MinDepth = 0;
D3Dvp.MaxDepth = 1;
deviceCtx->RSSetViewports(1, &D3Dvp);
}
void OVRBufferD3D11::destroy(const ovrSession& _session)
{
for (uint32_t ii = 0; ii < BX_COUNTOF(m_eyeRtv); ++ii)
{
DX_RELEASE(m_eyeRtv[ii], 0);
}
ovr_DestroyTextureSwapChain(_session, m_textureSwapChain);
m_depthBuffer->Release();
}
void OVRMirrorD3D11::create(const ovrSession& _session, int _width, int _height)
{
m_mirrorTextureDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
m_mirrorTextureDesc.Width = _width;
m_mirrorTextureDesc.Height = _height;
ovrResult result = ovr_CreateMirrorTextureDX(_session, s_renderD3D11->m_device, &m_mirrorTextureDesc, &m_mirrorTexture);
BX_WARN(OVR_SUCCESS(result), "Could not create D3D11 OVR mirror texture");
}
void OVRMirrorD3D11::destroy(const ovrSession& session)
{
if (NULL != m_mirrorTexture)
{
ovr_DestroyMirrorTexture(session, m_mirrorTexture);
m_mirrorTexture = NULL;
}
}
void OVRMirrorD3D11::blit(const ovrSession& _session)
{
if (NULL != m_mirrorTexture)
{
ID3D11Texture2D* tex = NULL;
ovr_GetMirrorTextureBufferDX(_session, m_mirrorTexture, IID_PPV_ARGS(&tex) );
ID3D11Texture2D* backBuffer;
DX_CHECK(s_renderD3D11->m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) );
s_renderD3D11->m_deviceCtx->CopyResource(backBuffer, tex);
DX_CHECK(s_renderD3D11->m_swapChain->Present(0, 0) );
DX_RELEASE(tex, 1);
DX_RELEASE(backBuffer, 0);
}
}
#endif // BGFX_CONFIG_USE_OVR
struct UavFormat
{
DXGI_FORMAT format[3];
@ -5077,8 +5067,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (m_ovr.isEnabled() )
{
m_ovr.getViewport(eye, &viewState.m_rect);
// commit previous eye to HMD and start rendering new frame
m_ovr.commitEye(eye);
m_ovr.renderEyeStart(eye);
}
else

View File

@ -59,6 +59,25 @@ BX_PRAGMA_DIAGNOSTIC_POP()
namespace bgfx { namespace d3d11
{
#if BGFX_CONFIG_USE_OVR
struct OVRBufferD3D11 : public OVRBufferI
{
virtual void create(const ovrSession& _session, int _eyeIdx) BX_OVERRIDE;
virtual void destroy(const ovrSession& _session) BX_OVERRIDE;
virtual void render(const ovrSession& _session) BX_OVERRIDE;
ID3D11RenderTargetView* m_eyeRtv[4];
ID3D11DepthStencilView* m_depthBuffer;
};
struct OVRMirrorD3D11 : public OVRMirrorI
{
virtual void create(const ovrSession& _session, int _width, int _height) BX_OVERRIDE;
virtual void destroy(const ovrSession& session) BX_OVERRIDE;
virtual void blit(const ovrSession& session) BX_OVERRIDE;
};
#endif // BGFX_CONFIG_USE_OVR
struct BufferD3D11
{
BufferD3D11()

View File

@ -1274,144 +1274,6 @@ namespace bgfx { namespace gl
BX_UNUSED(supported);
}
#if BGFX_CONFIG_USE_OVR
// Oculus Rift eye buffer
struct OVRBufferGL : public OVRBufferI
{
OVRBufferGL(const ovrSession& session, int eyeIdx)
{
ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session);
m_eyeTextureSize = ovr_GetFovTextureSize(session, (ovrEyeType)eyeIdx, hmdDesc.DefaultEyeFov[eyeIdx], 1.0f);
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Width = m_eyeTextureSize.w;
desc.Height = m_eyeTextureSize.h;
desc.MipLevels = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
ovr_CreateTextureSwapChainGL(session, &desc, &m_swapTextureChain);
int textureCount = 0;
ovr_GetTextureSwapChainLength(session, m_swapTextureChain, &textureCount);
for (int j = 0; j < textureCount; ++j)
{
GLuint chainTexId;
ovr_GetTextureSwapChainBufferGL(session, m_swapTextureChain, j, &chainTexId);
GL_CHECK(glBindTexture(GL_TEXTURE_2D, chainTexId));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
}
GL_CHECK(glGenFramebuffers(1, &m_eyeFbo));
// create depth buffer
GL_CHECK(glGenTextures(1, &m_depthBuffer));
GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_depthBuffer));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE));
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE));
GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize.w, m_eyeTextureSize.h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL));
}
void onRender(const ovrSession& session)
{
// set the current eye texture in swap chain
int curIndex;
ovr_GetTextureSwapChainCurrentIndex(session, m_swapTextureChain, &curIndex);
ovr_GetTextureSwapChainBufferGL(session, m_swapTextureChain, curIndex, &m_eyeTexId);
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo));
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0));
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0));
GL_CHECK(glViewport(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h));
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT));
}
void destroy(const ovrSession& session)
{
GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo));
GL_CHECK(glDeleteTextures(1, &m_depthBuffer));
ovr_DestroyTextureSwapChain(session, m_swapTextureChain);
}
GLuint m_eyeFbo;
GLuint m_eyeTexId;
GLuint m_depthBuffer;
};
// Oculus Rift mirror
struct OVRMirrorGL : public OVRMirrorI
{
void init(const ovrSession& session, int windowWidth, int windowHeight)
{
memset(&m_mirrorDesc, 0, sizeof(m_mirrorDesc));
m_mirrorDesc.Width = windowWidth;
m_mirrorDesc.Height = windowHeight;
m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
ovr_CreateMirrorTextureGL(session, &m_mirrorDesc, &m_mirrorTexture);
// Fallback to doing nothing if mirror was not created. This is to prevent errors with fast window resizes
if (!m_mirrorTexture)
return;
// Configure the mirror read buffer
GLuint texId;
ovr_GetMirrorTextureBufferGL(session, m_mirrorTexture, &texId);
GL_CHECK(glGenFramebuffers(1, &m_mirrorFBO));
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO));
GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0));
GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0));
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO));
BX_CHECK(false, "Could not initialize VR buffers!");
}
}
void destroy(const ovrSession& session)
{
if (!m_mirrorTexture)
return;
GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO));
ovr_DestroyMirrorTexture(session, m_mirrorTexture);
m_mirrorTexture = NULL;
}
void blit(const ovrSession& /*session*/)
{
if (!m_mirrorTexture)
return;
// Blit mirror texture to back buffer
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO));
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0));
GLint w = m_mirrorDesc.Width;
GLint h = m_mirrorDesc.Height;
GL_CHECK(glBlitFramebuffer(0, h, w, 0, 0, 0, w, h, GL_COLOR_BUFFER_BIT, GL_NEAREST));
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0));
}
GLuint m_mirrorFBO;
};
#endif // BGFX_CONFIG_USE_OVR
struct RendererContextGL : public RendererContextI
{
RendererContextGL()
@ -2244,7 +2106,16 @@ namespace bgfx { namespace gl
m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain);
}
m_ovr.swap(_hmd, true);
switch (m_ovr.swap(_hmd, true) )
{
case OVR::DeviceLost:
ovrPreReset();
break;
default:
break;
}
// need to swap GL render context even if OVR is enabled to get the mirror texture in the output
m_glctx.swap();
}
@ -2989,22 +2860,23 @@ namespace bgfx { namespace gl
void ovrPostReset()
{
#if BGFX_CONFIG_USE_OVR
if (m_resolution.m_flags & (BGFX_RESET_HMD | BGFX_RESET_HMD_DEBUG))
if (m_resolution.m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
{
if (m_ovr.postReset())
if (m_ovr.postReset() )
{
for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
for (uint32_t ii = 0; ii < 2; ++ii)
{
// eye buffers need to be initialized only once during application lifetime
if (!m_ovr.m_eyeBuffers[eyeIdx])
if (NULL == m_ovr.m_eyeBuffers[ii])
{
m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferGL(m_ovr.m_hmd, eyeIdx));
m_ovr.m_eyeBuffers[ii] = &m_ovrBuffers[ii];
m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii);
}
}
// recreate mirror texture
m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorGL);
m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
m_ovr.m_mirror = &m_ovrMirror;
m_ovr.m_mirror->create(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@ -3437,6 +3309,10 @@ namespace bgfx { namespace gl
const char* m_glslVersion;
OVR m_ovr;
#if BGFX_CONFIG_USE_OVR
OVRMirrorGL m_ovrMirror;
OVRBufferGL m_ovrBuffers[2];
#endif // BGFX_CONFIG_USE_OVR
};
RendererContextGL* s_renderGL;
@ -3455,6 +3331,129 @@ namespace bgfx { namespace gl
s_renderGL = NULL;
}
#if BGFX_CONFIG_USE_OVR
void OVRBufferGL::create(const ovrSession& _session, int _eyeIdx)
{
ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session);
m_eyeTextureSize = ovr_GetFovTextureSize(_session, ovrEyeType(_eyeIdx), hmdDesc.DefaultEyeFov[_eyeIdx], 1.0f);
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Width = m_eyeTextureSize.w;
desc.Height = m_eyeTextureSize.h;
desc.MipLevels = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
ovr_CreateTextureSwapChainGL(_session, &desc, &m_textureSwapChain);
int textureCount = 0;
ovr_GetTextureSwapChainLength(_session, m_textureSwapChain, &textureCount);
for (int j = 0; j < textureCount; ++j)
{
GLuint chainTexId;
ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain, j, &chainTexId);
GL_CHECK(glBindTexture(GL_TEXTURE_2D, chainTexId) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
}
GL_CHECK(glGenFramebuffers(1, &m_eyeFbo) );
// create depth buffer
GL_CHECK(glGenTextures(1, &m_depthBuffer) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_depthBuffer) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize.w, m_eyeTextureSize.h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL) );
}
void OVRBufferGL::render(const ovrSession& _session)
{
// set the current eye texture in swap chain
int curIndex;
ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &curIndex);
ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain, curIndex, &m_eyeTexId);
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0) );
GL_CHECK(glViewport(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h) );
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) );
}
void OVRBufferGL::destroy(const ovrSession& _session)
{
GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo) );
GL_CHECK(glDeleteTextures(1, &m_depthBuffer) );
ovr_DestroyTextureSwapChain(_session, m_textureSwapChain);
}
void OVRMirrorGL::create(const ovrSession& _session, int _width, int _height)
{
memset(&m_mirrorTextureDesc, 0, sizeof(m_mirrorTextureDesc) );
m_mirrorTextureDesc.Width = _width;
m_mirrorTextureDesc.Height = _height;
m_mirrorTextureDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
ovr_CreateMirrorTextureGL(_session, &m_mirrorTextureDesc, &m_mirrorTexture);
// Fallback to doing nothing if mirror was not created. This is to prevent errors with fast window resizes
if (!m_mirrorTexture)
return;
// Configure the mirror read buffer
GLuint texId;
ovr_GetMirrorTextureBufferGL(_session, m_mirrorTexture, &texId);
GL_CHECK(glGenFramebuffers(1, &m_mirrorFBO) );
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO) );
GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0) );
GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) );
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) );
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO) );
BX_CHECK(false, "Could not initialize VR buffers!");
}
}
void OVRMirrorGL::destroy(const ovrSession& _session)
{
if (NULL != m_mirrorTexture)
{
GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO) );
ovr_DestroyMirrorTexture(_session, m_mirrorTexture);
m_mirrorTexture = NULL;
}
}
void OVRMirrorGL::blit(const ovrSession& /*_session*/)
{
if (NULL != m_mirrorTexture)
{
// Blit mirror texture to back buffer
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO) );
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0) );
GLint width = m_mirrorTextureDesc.Width;
GLint height = m_mirrorTextureDesc.Height;
GL_CHECK(glBlitFramebuffer(0, height, width, 0, 0, 0, width, height, GL_COLOR_BUFFER_BIT, GL_NEAREST) );
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) );
}
}
#endif // BGFX_CONFIG_USE_OVR
const char* glslTypeName(GLuint _type)
{
#define GLSL_TYPE(_ty) case _ty: return #_ty
@ -5658,8 +5657,6 @@ namespace bgfx { namespace gl
if (m_ovr.isEnabled() )
{
m_ovr.getViewport(eye, &viewState.m_rect);
// commit previous eye to HMD and start rendering new frame
m_ovr.commitEye(eye);
m_ovr.renderEyeStart(eye);
}
else

View File

@ -901,6 +901,28 @@ namespace bgfx
namespace bgfx { namespace gl
{
#if BGFX_CONFIG_USE_OVR
struct OVRBufferGL : public OVRBufferI
{
virtual void create(const ovrSession& _session, int _eyeIdx) BX_OVERRIDE;
virtual void destroy(const ovrSession& _session) BX_OVERRIDE;
virtual void render(const ovrSession& _session) BX_OVERRIDE;
GLuint m_eyeFbo;
GLuint m_eyeTexId;
GLuint m_depthBuffer;
};
struct OVRMirrorGL : public OVRMirrorI
{
virtual void create(const ovrSession& _session, int _width, int _height) BX_OVERRIDE;
virtual void destroy(const ovrSession& _session) BX_OVERRIDE;
virtual void blit(const ovrSession& _session) BX_OVERRIDE;
GLuint m_mirrorFBO;
};
#endif // BGFX_CONFIG_USE_OVR
void dumpExtensions(const char* _extensions);
const char* glEnumName(GLenum _enum);

View File

@ -477,6 +477,19 @@ int main(int _argc, const char* _argv[])
ImageMip dstMip;
imageGetRawData(imageContainer, 0, 0, NULL, 0, dstMip);
if (mip.m_width != dstMip.m_width
&& mip.m_height != dstMip.m_height)
{
printf("Invalid input image size %dx%d, it must be at least %dx%d to be converted to %s format.\n"
, mip.m_width
, mip.m_height
, dstMip.m_width
, dstMip.m_height
, getName(format)
);
return EXIT_FAILURE;
}
uint32_t size = imageGetSize(TextureFormat::RGBA32F, dstMip.m_width, dstMip.m_height);
temp = BX_ALLOC(&allocator, size);
float* rgba = (float*)temp;
@ -528,6 +541,19 @@ int main(int _argc, const char* _argv[])
ImageMip dstMip;
imageGetRawData(imageContainer, 0, 0, NULL, 0, dstMip);
if (mip.m_width != dstMip.m_width
&& mip.m_height != dstMip.m_height)
{
printf("Invalid input image size %dx%d, it must be at least %dx%d to be converted to %s format.\n"
, mip.m_width
, mip.m_height
, dstMip.m_width
, dstMip.m_height
, getName(format)
);
return EXIT_FAILURE;
}
uint32_t size = imageGetSize(TextureFormat::RGBA8, dstMip.m_width, dstMip.m_height);
temp = BX_ALLOC(&allocator, size);
memset(temp, 0, size);