-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Nvidia atw updates #355
base: master
Are you sure you want to change the base?
Nvidia atw updates #355
Changes from all commits
7230ca7
753d0dd
290553b
0ecee29
7b66b0c
9675115
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,7 @@ Russ Taylor <[email protected]> | |
#include <iostream> | ||
#include <string> | ||
#include <chrono> | ||
#include <thread> | ||
#include <stdlib.h> // For exit() | ||
|
||
using namespace DirectX; | ||
|
@@ -117,7 +118,7 @@ void RenderView( | |
|
||
// draw room | ||
simpleShader.use(device, context, xm_projectionD3D, xm_viewD3D, identity); | ||
roomCube.draw(device, context); | ||
roomCube.draw(device, context); | ||
} | ||
|
||
void Usage(std::string name) { | ||
|
@@ -135,8 +136,10 @@ struct FrameInfo { | |
}; | ||
|
||
int main(int argc, char* argv[]) { | ||
std::cout << "Render thread id: " << std::this_thread::get_id() << std::endl; | ||
|
||
// Parse the command line | ||
int delayMilliSeconds = 500; | ||
int delayMilliSeconds = 0; | ||
int realParams = 0; | ||
for (int i = 1; i < argc; i++) { | ||
if (argv[i][0] == '-') { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,7 @@ | |
#include <string> | ||
#include <stdlib.h> // For exit() | ||
#include <chrono> | ||
#include <thread> | ||
|
||
using namespace DirectX; | ||
|
||
|
@@ -88,8 +89,8 @@ void myButtonCallback(void* userdata, const OSVR_TimeValue* /*timestamp*/, | |
// Callbacks to draw things in world space, left-hand space, and right-hand | ||
// space. | ||
void RenderView( | ||
const OSVR_RenderInfoD3D11& renderInfo //< Info needed to render | ||
, | ||
size_t eye, | ||
const OSVR_RenderInfoD3D11& renderInfo, //< Info needed to render | ||
ID3D11RenderTargetView* renderTargetView, | ||
ID3D11DepthStencilView* depthStencilView) { | ||
|
||
|
@@ -103,17 +104,12 @@ void RenderView( | |
context->OMSetRenderTargets(1, &renderTargetView, depthStencilView); | ||
|
||
// Set up the viewport we're going to draw into. | ||
CD3D11_VIEWPORT viewport(static_cast<float>(renderInfo.viewport.left), | ||
static_cast<float>(renderInfo.viewport.lower), | ||
static_cast<float>(renderInfo.viewport.width), | ||
static_cast<float>(renderInfo.viewport.height)); | ||
context->RSSetViewports(1, &viewport); | ||
CD3D11_VIEWPORT viewport(static_cast<float>(eye == 0 ? 0 : renderInfo.viewport.width), | ||
static_cast<float>(renderInfo.viewport.lower), | ||
static_cast<float>(renderInfo.viewport.width), | ||
static_cast<float>(renderInfo.viewport.height)); | ||
|
||
// Make a grey background | ||
FLOAT colorRgba[4] = {0.3f, 0.3f, 0.3f, 1.0f}; | ||
context->ClearRenderTargetView(renderTargetView, colorRgba); | ||
context->ClearDepthStencilView( | ||
depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); | ||
context->RSSetViewports(1, &viewport); | ||
|
||
OSVR_PoseState_to_D3D(viewD3D, renderInfo.pose); | ||
OSVR_Projection_to_D3D(projectionD3D, | ||
|
@@ -132,6 +128,7 @@ void Usage(std::string name) { | |
} | ||
|
||
int main(int argc, char* argv[]) { | ||
std::cout << "Render thread id: " << std::this_thread::get_id(); | ||
// Parse the command line | ||
int realParams = 0; | ||
for (int i = 1; i < argc; i++) { | ||
|
@@ -153,6 +150,23 @@ int main(int argc, char* argv[]) { | |
osvr::clientkit::ClientContext context( | ||
"osvr.RenderManager.D3DPresentExample3D"); | ||
|
||
// Wait for good status on context | ||
{ | ||
auto ctxInitStart = std::chrono::system_clock::now(); | ||
bool timeout = false; | ||
do { | ||
context.update(); | ||
auto ctxInitEnd = std::chrono::system_clock::now(); | ||
std::chrono::duration<double> elapsedSec = ctxInitEnd - ctxInitStart; | ||
int secs = static_cast<int>(elapsedSec.count()); | ||
timeout = secs >= 2; | ||
} while (!context.checkStatus() && !timeout); | ||
if (timeout) { | ||
std::cerr << "Timed out waiting for the ClientContext to connect to the OSVR server."; | ||
return 1; | ||
} | ||
} | ||
|
||
// Construct button devices and connect them to a callback | ||
// that will set the "quit" variable to true when it is | ||
// pressed. Use button "1" on the left-hand or | ||
|
@@ -246,22 +260,23 @@ int main(int argc, char* argv[]) { | |
std::vector<ID3D11Texture2D*> depthStencilTextures; | ||
std::vector<ID3D11DepthStencilView*> depthStencilViews; | ||
|
||
double width = renderInfo[0].viewport.width + renderInfo[1].viewport.width; | ||
double height = renderInfo[0].viewport.height; | ||
|
||
HRESULT hr; | ||
for (size_t i = 0; i < numRenderInfo; i++) { | ||
for (size_t i = 0; i < 2; i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why make this less general? A monocular view onscreen is possible when we use numRenderInfo and not when we use 2. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The 2 here has a different meaning than the numRenderInfo it replaces. It's no longer the number of render info but the number of buffers in the client-side swap chain, which the client controls and which we only support 1 or 2 at the moment. For reference, these are the only configurations we support at the moment (i.e. for RegisterRenderBuffers): RenderManager currently has no generic way to support all scenarios and so the client has to make assumptions in order to fit into one of the four supported configurations above - e.g. that there are going to be two render infos, each corresponding to an eye. Ideally, the client would request the suggested viewports and buffer sizes and number for a given client preference (one buffer per eye or all eyes in one buffer X double buffered or not double buffered) and then RenderManager would give the client 1) how many buffers to create, 2) what sizes for each buffer, 3) which RenderInfos to render for which buffers and 4) what viewports on THOSE buffers to use (as opposed to the viewports RenderInfo has, which assumes one buffer per eye). |
||
|
||
// The color buffer for this eye. We need to put this into | ||
// a generic structure for the Present function, but we only need | ||
// to fill in the Direct3D portion. | ||
// Note that this texture format must be RGBA and unsigned byte, | ||
// so that we can present it to Direct3D for DirectMode. | ||
ID3D11Texture2D* D3DTexture = nullptr; | ||
unsigned width = static_cast<int>(renderInfo[i].viewport.width); | ||
unsigned height = static_cast<int>(renderInfo[i].viewport.height); | ||
|
||
// Initialize a new render target texture description. | ||
D3D11_TEXTURE2D_DESC textureDesc = {}; | ||
textureDesc.Width = width; | ||
textureDesc.Height = height; | ||
textureDesc.Width = static_cast<UINT>(width); | ||
textureDesc.Height = static_cast<UINT>(height); | ||
textureDesc.MipLevels = 1; | ||
textureDesc.ArraySize = 1; | ||
textureDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; | ||
|
@@ -317,8 +332,8 @@ int main(int argc, char* argv[]) { | |
textureDescription.SampleDesc.Quality = 0; | ||
textureDescription.Usage = D3D11_USAGE_DEFAULT; | ||
textureDescription.BindFlags = D3D11_BIND_DEPTH_STENCIL; | ||
textureDescription.Width = width; | ||
textureDescription.Height = height; | ||
textureDescription.Width = static_cast<UINT>(width); | ||
textureDescription.Height = static_cast<UINT>(height); | ||
textureDescription.MipLevels = 1; | ||
textureDescription.ArraySize = 1; | ||
textureDescription.CPUAccessFlags = 0; | ||
|
@@ -370,8 +385,7 @@ int main(int argc, char* argv[]) { | |
|
||
// Front-facing stencil operations | ||
depthStencilDescription.FrontFace.StencilFailOp = D3D11_STENCIL_OP_KEEP; | ||
depthStencilDescription.FrontFace.StencilDepthFailOp = | ||
D3D11_STENCIL_OP_INCR; | ||
depthStencilDescription.FrontFace.StencilDepthFailOp = D3D11_STENCIL_OP_INCR; | ||
depthStencilDescription.FrontFace.StencilPassOp = D3D11_STENCIL_OP_KEEP; | ||
depthStencilDescription.FrontFace.StencilFunc = D3D11_COMPARISON_ALWAYS; | ||
|
||
|
@@ -399,7 +413,7 @@ int main(int argc, char* argv[]) { | |
osvrDestroyRenderManager(render); | ||
return -4; | ||
} | ||
for (size_t i = 0; i < numRenderInfo; i++) { | ||
for (size_t i = 0; i < renderBuffers.size(); i++) { | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerRegisterRenderBufferD3D11( | ||
registerBufferState, renderBuffers[i]))) { | ||
std::cerr << "Could not register render buffer " << i << std::endl; | ||
|
@@ -408,107 +422,129 @@ int main(int argc, char* argv[]) { | |
} | ||
} | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerFinishRegisterRenderBuffers( | ||
render, registerBufferState, false))) { | ||
render, registerBufferState, true))) { | ||
std::cerr << "Could not start finish registering render buffers" << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return -6; | ||
} | ||
|
||
// Timing of frame rates | ||
size_t count = 0; | ||
size_t frameIndex = 0; | ||
std::chrono::time_point<std::chrono::system_clock> start, end; | ||
start = std::chrono::system_clock::now(); | ||
|
||
// Continue rendering until it is time to quit. | ||
while (!quit) { | ||
// Update the context so we get our callbacks called and | ||
// update tracker state. | ||
context.update(); | ||
|
||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoCollection( | ||
render, renderParams, &renderInfoCollection))) { | ||
std::cerr << "Could not get render info" << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 105; | ||
} | ||
osvrRenderManagerGetNumRenderInfoInCollection(renderInfoCollection, &numRenderInfo); | ||
|
||
|
||
renderInfo.clear(); | ||
for (OSVR_RenderInfoCount i = 0; i < numRenderInfo; i++) { | ||
OSVR_RenderInfoD3D11 info; | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoFromCollectionD3D11( | ||
renderInfoCollection, i, &info))) { | ||
std::cerr << "Could not get render info " << i | ||
<< std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 106; | ||
} | ||
renderInfo.push_back(info); | ||
} | ||
osvrRenderManagerReleaseRenderInfoCollection(renderInfoCollection); | ||
|
||
// Render into each buffer using the specified information. | ||
for (size_t i = 0; i < renderInfo.size(); i++) { | ||
renderInfo[i].library.context->OMSetDepthStencilState( | ||
depthStencilState, 1); | ||
RenderView(renderInfo[i], renderBuffers[i].colorBufferView, | ||
depthStencilViews[i]); | ||
} | ||
|
||
// Every other second, we show a black screen to test how | ||
// a game engine might blank it between scenes. Every even | ||
// second, we display the video. | ||
end = std::chrono::system_clock::now(); | ||
std::chrono::duration<double> elapsed_sec = end - start; | ||
int secs = static_cast<int>(elapsed_sec.count()); | ||
|
||
if (secs % 2 == 0) { | ||
// Send the rendered results to the screen | ||
OSVR_RenderManagerPresentState presentState; | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerStartPresentRenderBuffers( | ||
&presentState))) { | ||
std::cerr << "Could not start presenting render buffers" << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 201; | ||
} | ||
OSVR_ViewportDescription fullView; | ||
fullView.left = fullView.lower = 0; | ||
fullView.width = fullView.height = 1; | ||
for (size_t i = 0; i < numRenderInfo; i++) { | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerPresentRenderBufferD3D11( | ||
presentState, renderBuffers[i], renderInfo[i], fullView))) { | ||
std::cerr << "Could not present render buffer " << i << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 202; | ||
} | ||
} | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerFinishPresentRenderBuffers( | ||
render, presentState, renderParams, false))) { | ||
std::cerr << "Could not finish presenting render buffers" << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 203; | ||
} | ||
} else { | ||
// send a black screen. | ||
OSVR_RGB_FLOAT black; | ||
black.r = black.g = black.b = 0; | ||
osvrRenderManagerPresentSolidColorf(render, black); | ||
} | ||
|
||
// Timing information | ||
if (elapsed_sec.count() >= 2) { | ||
std::chrono::duration<double, std::micro> elapsed_usec = | ||
end - start; | ||
double usec = elapsed_usec.count(); | ||
std::cout << "Rendering at " << count / (usec * 1e-6) << " fps" | ||
<< std::endl; | ||
start = end; | ||
count = 0; | ||
} | ||
count++; | ||
} | ||
|
||
while (!quit) { | ||
size_t renderBufferIndex = frameIndex % 2; | ||
frameIndex++; | ||
|
||
// Update the context so we get our callbacks called and | ||
// update tracker state. | ||
context.update(); | ||
|
||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoCollection( | ||
render, renderParams, &renderInfoCollection))) { | ||
std::cerr << "Could not get render info" << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 105; | ||
} | ||
osvrRenderManagerGetNumRenderInfoInCollection(renderInfoCollection, &numRenderInfo); | ||
|
||
|
||
renderInfo.clear(); | ||
for (OSVR_RenderInfoCount i = 0; i < numRenderInfo; i++) { | ||
OSVR_RenderInfoD3D11 info; | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerGetRenderInfoFromCollectionD3D11( | ||
renderInfoCollection, i, &info))) { | ||
std::cerr << "Could not get render info " << i | ||
<< std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 106; | ||
} | ||
renderInfo.push_back(info); | ||
} | ||
osvrRenderManagerReleaseRenderInfoCollection(renderInfoCollection); | ||
|
||
// Set up to render to the textures for this eye | ||
auto renderTargetView = renderBuffers[renderBufferIndex].colorBufferView; | ||
auto depthStencilView = depthStencilViews[renderBufferIndex]; | ||
auto context = renderInfo[0].library.context; | ||
context->OMSetRenderTargets(1, &renderTargetView, depthStencilView); | ||
|
||
// Set up the viewport we're going to draw into. | ||
//CD3D11_VIEWPORT viewport(static_cast<float>(renderInfo.viewport.left), | ||
// static_cast<float>(renderInfo.viewport.lower), | ||
// static_cast<float>(renderInfo.viewport.width), | ||
// static_cast<float>(renderInfo.viewport.height)); | ||
CD3D11_VIEWPORT viewport( | ||
0.0f, | ||
0.0f, | ||
static_cast<float>(width), | ||
static_cast<float>(height)); | ||
|
||
context->RSSetViewports(1, &viewport); | ||
|
||
// Make a grey background | ||
FLOAT colorRgba[4] = { 0.3f, 0.3f, 0.3f, 1.0f }; | ||
context->ClearRenderTargetView(renderTargetView, colorRgba); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there are two windows for the two eyes, we're going to have to clear both of them here, not just one of them. |
||
context->ClearDepthStencilView( | ||
depthStencilView, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0); | ||
|
||
// Render into each buffer using the specified information. | ||
for (size_t i = 0; i < renderInfo.size(); i++) { | ||
renderInfo[i].library.context->OMSetDepthStencilState( | ||
depthStencilState, 1); | ||
RenderView(i, renderInfo[i], renderTargetView, depthStencilView); | ||
} | ||
|
||
// Every other second, we show a black screen to test how | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code to do the black swap was removed, but this comment was not. |
||
// a game engine might blank it between scenes. Every even | ||
// second, we display the video. | ||
end = std::chrono::system_clock::now(); | ||
std::chrono::duration<double> elapsed_sec = end - start; | ||
int secs = static_cast<int>(elapsed_sec.count()); | ||
|
||
// Send the rendered results to the screen | ||
OSVR_RenderManagerPresentState presentState; | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerStartPresentRenderBuffers(&presentState))) { | ||
std::cerr << "Could not start presenting render buffers" << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 201; | ||
} | ||
|
||
for (size_t i = 0; i < numRenderInfo; i++) { | ||
OSVR_ViewportDescription normalizedViewport; | ||
normalizedViewport.left = i == 0 ? 0 : 0.5; | ||
normalizedViewport.lower = 0; | ||
normalizedViewport.width = 0.5; | ||
normalizedViewport.height = 1.0; | ||
|
||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerPresentRenderBufferD3D11( | ||
presentState, renderBuffers[renderBufferIndex], renderInfo[i], normalizedViewport))) { | ||
std::cerr << "Could not present render buffer " << i << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 202; | ||
} | ||
} | ||
if ((OSVR_RETURN_SUCCESS != osvrRenderManagerFinishPresentRenderBuffers( | ||
render, presentState, renderParams, false))) { | ||
std::cerr << "Could not finish presenting render buffers" << std::endl; | ||
osvrDestroyRenderManager(render); | ||
return 203; | ||
} | ||
|
||
// Timing information | ||
if (elapsed_sec.count() >= 2) { | ||
std::chrono::duration<double, std::micro> elapsed_usec = end - start; | ||
double usec = elapsed_usec.count(); | ||
std::cout << "Rendering at " << count / (usec * 1e-6) << " fps" | ||
<< std::endl; | ||
start = end; | ||
count = 0; | ||
} | ||
count++; | ||
} | ||
// Clean up after ourselves. | ||
// @todo | ||
|
||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be handled by RenderManager, not by the application. The viewport should have been set correctly by the osvrRenderManagerGetRenderInfoFromCollectionD3D11() call.