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 "-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 "-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 "-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 #endif
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used #pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used

View File

@ -5,6 +5,8 @@
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" # pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
# endif // __clang__ # endif // __clang__
#elif defined(_MSC_VER) #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: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:4456) // warning C4456: declaration of 'k' hides previous local declaration
# pragma warning(disable:4457) // warning C4457: declaration of 'y' hides function parameter # 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 void init(int _argc, char** _argv) BX_OVERRIDE
{ {
Args args(_argc, _argv); Args args(_argc, _argv);
m_width = 1280; m_width = 1280;
m_height = 720; m_height = 720;
m_debug = BGFX_DEBUG_TEXT; m_debug = BGFX_DEBUG_TEXT;
@ -143,7 +143,7 @@ class ExampleCubes : public entry::AppI
{ {
float view[16]; float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); 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. // Set view 0 default viewport.
// //

View File

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

View File

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

View File

@ -160,7 +160,7 @@ class ExampleInstancing : public entry::AppI
{ {
float view[16]; float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); 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. // Set view 0 default viewport.
// //

View File

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

View File

@ -174,7 +174,7 @@ class ExampleLod : public entry::AppI
{ {
float view[16]; float view[16];
bx::mtxQuatTranslationHMD(view, hmd->eye[0].rotation, eye); 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. // Set view 0 default viewport.
// //

View File

@ -305,7 +305,7 @@ int _main_(int _argc, char** _argv)
float tmp[16]; float tmp[16];
bx::mtxMul(tmp, view, viewHead); 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. // 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) ) 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; int64_t now = bx::getHPCounter() - m_timeOffset;
static int64_t last = now; static int64_t last = now;
const int64_t frameTime = now - last; const int64_t frameTime = now - last;
@ -89,9 +86,24 @@ class DebugDrawApp : public entry::AppI
cameraGetViewMtx(view); cameraGetViewMtx(view);
float proj[16]; 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] = {}; 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); ddDrawCircle(Axis::Z, -8.0f, 0.0f, 0.0f, 1.25f, 2.0f);
ddPop(); 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); ddDrawOrb(-11.0f, 0.0f, 0.0f, 1.0f);
ddEnd(); ddEnd();

View File

@ -1018,6 +1018,132 @@ struct DebugDraw
close(); 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) void drawAxis(float _x, float _y, float _z, float _len, Axis::Enum _highlight)
{ {
push(); push();
@ -1271,18 +1397,19 @@ private:
bgfx::allocTransientIndexBuffer(&tib, m_indexPos); bgfx::allocTransientIndexBuffer(&tib, m_indexPos);
memcpy(tib.data, m_indices, m_indexPos * sizeof(uint16_t) ); memcpy(tib.data, m_indices, m_indexPos * sizeof(uint16_t) );
const Attrib& attrib = m_attrib[m_stack];
bgfx::setVertexBuffer(&tvb); bgfx::setVertexBuffer(&tvb);
bgfx::setIndexBuffer(&tib); bgfx::setIndexBuffer(&tib);
bgfx::setState(0 bgfx::setState(0
| BGFX_STATE_RGB_WRITE | BGFX_STATE_RGB_WRITE
| BGFX_STATE_PT_LINES | BGFX_STATE_PT_LINES
| (m_depthTestLess ? BGFX_STATE_DEPTH_TEST_LEQUAL : BGFX_STATE_DEPTH_TEST_GEQUAL) | attrib.m_state
| BGFX_STATE_DEPTH_WRITE
| BGFX_STATE_LINEAA | BGFX_STATE_LINEAA
| BGFX_STATE_BLEND_ALPHA | BGFX_STATE_BLEND_ALPHA
); );
bgfx::setTransform(m_mtx); 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); 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); 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) void ddDrawAxis(float _x, float _y, float _z, float _len, Axis::Enum _hightlight)
{ {
s_dd.drawAxis(_x, _y, _z, _len, _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 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); 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] _handle Uniform.
/// @param[in] _value Pointer to uniform data. /// @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`. /// @attention C99 equivalent is `bgfx_set_uniform`.
/// ///

View File

@ -51,11 +51,23 @@ function bgfxProject(_name, _kind, _defines)
if _OPTIONS["with-ovr"] then if _OPTIONS["with-ovr"] then
defines { defines {
-- "BGFX_CONFIG_MULTITHREADED=0",
"BGFX_CONFIG_USE_OVR=1", "BGFX_CONFIG_USE_OVR=1",
} }
includedirs { includedirs {
"$(OVR_DIR)/LibOVR/Include", "$(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 end
configuration { "Debug" } configuration { "Debug" }

View File

@ -1431,16 +1431,16 @@ namespace bgfx
m_indexBufferHandle.free(_frame->m_freeIndexBufferHandle[ii].idx); 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) for (uint16_t ii = 0, num = _frame->m_numFreeVertexBufferHandles; ii < num; ++ii)
{ {
destroyVertexBufferInternal(_frame->m_freeVertexBufferHandle[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) for (uint16_t ii = 0, num = _frame->m_numFreeShaderHandles; ii < num; ++ii)
{ {
m_shaderHandle.free(_frame->m_freeShaderHandle[ii].idx); m_shaderHandle.free(_frame->m_freeShaderHandle[ii].idx);

View File

@ -3617,7 +3617,7 @@ namespace bgfx
{ {
BGFX_CHECK_HANDLE("setUniform", m_uniformHandle, _handle); BGFX_CHECK_HANDLE("setUniform", m_uniformHandle, _handle);
UniformRef& uniform = m_uniformRef[_handle.idx]; 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) ) if (BX_ENABLED(BGFX_CONFIG_DEBUG_UNIFORM) )
{ {
BX_CHECK(m_uniformSet.end() == m_uniformSet.find(_handle.idx) 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 USAMPLER2D(_name, _reg) uniform usampler2D _name
# define ISAMPLER3D(_name, _reg) uniform isampler3D _name # define ISAMPLER3D(_name, _reg) uniform isampler3D _name
# define USAMPLER3D(_name, _reg) uniform usampler3D _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); } vec4 bgfxTexture2D(sampler2D _sampler, vec2 _coord)
ivec4 texture3D(isampler3D _sampler, vec3 _coord) { return texture(_sampler, _coord); } {
uvec4 texture3D(usampler3D _sampler, vec3 _coord) { return texture(_sampler, _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 # endif // BGFX_SHADER_LANGUAGE_GLSL >= 130
vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); } vec3 instMul(vec3 _vec, mat3 _mtx) { return mul(_vec, _mtx); }

View File

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

View File

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

View File

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

View File

@ -601,170 +601,6 @@ namespace bgfx { namespace d3d11
static PFN_GET_DEBUG_INTERFACE1 DXGIGetDebugInterface1; static PFN_GET_DEBUG_INTERFACE1 DXGIGetDebugInterface1;
#endif // USE_D3D11_DYNAMIC_LIB #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 struct RendererContextD3D11 : public RendererContextI
{ {
RendererContextD3D11() 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; IDXGIDevice* device = NULL;
IDXGIAdapter* adapter = NULL; IDXGIAdapter* adapter = NULL;
hr = E_FAIL; hr = E_FAIL;
@ -1386,7 +1229,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
} }
{ {
UniformHandle handle = BGFX_INVALID_HANDLE; UniformHandle handle = BGFX_INVALID_HANDLE;
for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii) for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
{ {
@ -2350,9 +2192,18 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (SUCCEEDED(hr) ) if (SUCCEEDED(hr) )
{ {
if (!m_ovr.swap(_hmd, false) ) switch (m_ovr.swap(_hmd, false) )
{ {
case OVR::NotEnabled:
hr = m_swapChain->Present(syncInterval, 0); 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 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 // 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 // recreate mirror texture
m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorDX11(m_device, m_deviceCtx, m_swapChain)); m_ovr.m_mirror = &m_ovrMirror;
m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height); m_ovr.m_mirror->create(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
} }
} }
#endif // BGFX_CONFIG_USE_OVR #endif // BGFX_CONFIG_USE_OVR
@ -3657,6 +3509,10 @@ BX_PRAGMA_DIAGNOSTIC_POP();
bool m_timerQuerySupport; bool m_timerQuerySupport;
OVR m_ovr; OVR m_ovr;
#if BGFX_CONFIG_USE_OVR
OVRMirrorD3D11 m_ovrMirror;
OVRBufferD3D11 m_ovrBuffers[2];
#endif // BGFX_CONFIG_USE_OVR
}; };
static RendererContextD3D11* s_renderD3D11; static RendererContextD3D11* s_renderD3D11;
@ -3709,6 +3565,140 @@ BX_PRAGMA_DIAGNOSTIC_POP();
agsDriverExtensions_MultiDrawIndexedInstancedIndirect(s_renderD3D11->m_ags, _numDrawIndirect, _ptr, _offset, _stride); 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 struct UavFormat
{ {
DXGI_FORMAT format[3]; DXGI_FORMAT format[3];
@ -5077,8 +5067,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (m_ovr.isEnabled() ) if (m_ovr.isEnabled() )
{ {
m_ovr.getViewport(eye, &viewState.m_rect); 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); m_ovr.renderEyeStart(eye);
} }
else else

View File

@ -59,6 +59,25 @@ BX_PRAGMA_DIAGNOSTIC_POP()
namespace bgfx { namespace d3d11 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 struct BufferD3D11
{ {
BufferD3D11() BufferD3D11()

View File

@ -1274,144 +1274,6 @@ namespace bgfx { namespace gl
BX_UNUSED(supported); 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 struct RendererContextGL : public RendererContextI
{ {
RendererContextGL() RendererContextGL()
@ -2244,7 +2106,16 @@ namespace bgfx { namespace gl
m_glctx.swap(m_frameBuffers[m_windows[ii].idx].m_swapChain); 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 // need to swap GL render context even if OVR is enabled to get the mirror texture in the output
m_glctx.swap(); m_glctx.swap();
} }
@ -2989,22 +2860,23 @@ namespace bgfx { namespace gl
void ovrPostReset() void ovrPostReset()
{ {
#if BGFX_CONFIG_USE_OVR #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 // 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 // recreate mirror texture
m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorGL); m_ovr.m_mirror = &m_ovrMirror;
m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height); m_ovr.m_mirror->create(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
} }
} }
#endif // BGFX_CONFIG_USE_OVR #endif // BGFX_CONFIG_USE_OVR
@ -3437,6 +3309,10 @@ namespace bgfx { namespace gl
const char* m_glslVersion; const char* m_glslVersion;
OVR m_ovr; OVR m_ovr;
#if BGFX_CONFIG_USE_OVR
OVRMirrorGL m_ovrMirror;
OVRBufferGL m_ovrBuffers[2];
#endif // BGFX_CONFIG_USE_OVR
}; };
RendererContextGL* s_renderGL; RendererContextGL* s_renderGL;
@ -3455,6 +3331,129 @@ namespace bgfx { namespace gl
s_renderGL = NULL; 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) const char* glslTypeName(GLuint _type)
{ {
#define GLSL_TYPE(_ty) case _ty: return #_ty #define GLSL_TYPE(_ty) case _ty: return #_ty
@ -5658,8 +5657,6 @@ namespace bgfx { namespace gl
if (m_ovr.isEnabled() ) if (m_ovr.isEnabled() )
{ {
m_ovr.getViewport(eye, &viewState.m_rect); 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); m_ovr.renderEyeStart(eye);
} }
else else

View File

@ -901,6 +901,28 @@ namespace bgfx
namespace bgfx { namespace gl 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); void dumpExtensions(const char* _extensions);
const char* glEnumName(GLenum _enum); const char* glEnumName(GLenum _enum);

View File

@ -477,6 +477,19 @@ int main(int _argc, const char* _argv[])
ImageMip dstMip; ImageMip dstMip;
imageGetRawData(imageContainer, 0, 0, NULL, 0, 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); uint32_t size = imageGetSize(TextureFormat::RGBA32F, dstMip.m_width, dstMip.m_height);
temp = BX_ALLOC(&allocator, size); temp = BX_ALLOC(&allocator, size);
float* rgba = (float*)temp; float* rgba = (float*)temp;
@ -528,6 +541,19 @@ int main(int _argc, const char* _argv[])
ImageMip dstMip; ImageMip dstMip;
imageGetRawData(imageContainer, 0, 0, NULL, 0, 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); uint32_t size = imageGetSize(TextureFormat::RGBA8, dstMip.m_width, dstMip.m_height);
temp = BX_ALLOC(&allocator, size); temp = BX_ALLOC(&allocator, size);
memset(temp, 0, size); memset(temp, 0, size);