Baseline working openvr code

This commit is contained in:
James Urquhart 2016-04-17 22:19:42 +01:00
parent e239d106f5
commit ba91478fad
23 changed files with 1463 additions and 457 deletions

View file

@ -38,8 +38,8 @@
#include "gfx/gfxDrawUtil.h"
#include "gfx/gfxDebugEvent.h"
#include "core/stream/fileStream.h"
GFXTextureObject *gLastStereoTexture = NULL;
#include "platform/output/IDisplayDevice.h"
#include "T3D/gameBase/extended/extendedMove.h"
#define TS_OVERLAY_SCREEN_WIDTH 0.75
@ -66,6 +66,7 @@ ImplementEnumType( GuiTSRenderStyles,
"@ingroup Gui3D" )
{ GuiTSCtrl::RenderStyleStandard, "standard" },
{ GuiTSCtrl::RenderStyleStereoSideBySide, "stereo side by side" },
{ GuiTSCtrl::RenderStyleStereoSeparate, "stereo separate" },
EndImplementEnumType;
//-----------------------------------------------------------------------------
@ -353,32 +354,111 @@ static FovPort CalculateFovPortForCanvas(const RectI viewport, const CameraQuery
return fovPort;
}
void GuiTSCtrl::_internalRender(RectI viewport, Frustum &frustum)
{
GFXTransformSaver saver;
Point2I renderSize = viewport.extent;
if (mReflectPriority > 0)
{
// Get the total reflection priority.
F32 totalPriority = 0;
for (U32 i = 0; i < smAwakeTSCtrls.size(); i++)
if (smAwakeTSCtrls[i]->isVisible())
totalPriority += smAwakeTSCtrls[i]->mReflectPriority;
REFLECTMGR->update(mReflectPriority / totalPriority,
getExtent(),
mLastCameraQuery);
}
if (mForceFOV != 0)
mLastCameraQuery.fov = mDegToRad(mForceFOV);
if (mCameraZRot)
{
MatrixF rotMat(EulerF(0, 0, mDegToRad(mCameraZRot)));
mLastCameraQuery.cameraMatrix.mul(rotMat);
}
GFX->setViewport(viewport);
// Clear the zBuffer so GUI doesn't hose object rendering accidentally
GFX->clear(GFXClearZBuffer, ColorI(20, 20, 20), 1.0f, 0);
GFX->setFrustum(frustum);
mSaveProjection = GFX->getProjectionMatrix();
if (mLastCameraQuery.ortho)
{
mOrthoWidth = frustum.getWidth();
mOrthoHeight = frustum.getHeight();
}
// We're going to be displaying this render at size of this control in
// pixels - let the scene know so that it can calculate e.g. reflections
// correctly for that final display result.
gClientSceneGraph->setDisplayTargetResolution(renderSize);
// Set the GFX world matrix to the world-to-camera transform, but don't
// change the cameraMatrix in mLastCameraQuery. This is because
// mLastCameraQuery.cameraMatrix is supposed to contain the camera-to-world
// transform. In-place invert would save a copy but mess up any GUIs that
// depend on that value.
MatrixF worldToCamera = mLastCameraQuery.cameraMatrix;
worldToCamera.inverse();
GFX->setWorldMatrix(worldToCamera);
mSaveProjection = GFX->getProjectionMatrix();
mSaveModelview = GFX->getWorldMatrix();
mSaveViewport = viewport;
mSaveWorldToScreenScale = GFX->getWorldToScreenScale();
mSaveFrustum = GFX->getFrustum();
mSaveFrustum.setTransform(mLastCameraQuery.cameraMatrix);
// Set the default non-clip projection as some
// objects depend on this even in non-reflect cases.
gClientSceneGraph->setNonClipProjection(mSaveProjection);
// Give the post effect manager the worldToCamera, and cameraToScreen matrices
PFXMGR->setFrameMatrices(mSaveModelview, mSaveProjection);
renderWorld(viewport);
DebugDrawer::get()->render();
// Restore the previous matrix state before
// we begin rendering the child controls.
saver.restore();
}
//-----------------------------------------------------------------------------
void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
{
// Save the current transforms so we can restore
// Save the current transforms so we can restore
// it for child control rendering below.
GFXTransformSaver saver;
bool renderingToTarget = false;
if(!processCameraQuery(&mLastCameraQuery))
if (!processCameraQuery(&mLastCameraQuery))
{
// We have no camera, but render the GUI children
// anyway. This makes editing GuiTSCtrl derived
// controls easier in the GuiEditor.
renderChildControls( offset, updateRect );
renderChildControls(offset, updateRect);
return;
}
GFXTargetRef origTarget = GFX->getActiveRenderTarget();
U32 origStyle = GFX->getCurrentRenderStyle();
// Set up the appropriate render style
U32 prevRenderStyle = GFX->getCurrentRenderStyle();
Point2F prevProjectionOffset = GFX->getCurrentProjectionOffset();
Point2I renderSize = getExtent();
Frustum frustum;
if(mRenderStyle == RenderStyleStereoSideBySide)
if (mRenderStyle == RenderStyleStereoSideBySide)
{
GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSideBySide);
GFX->setCurrentProjectionOffset(mLastCameraQuery.projectionOffset);
@ -399,13 +479,13 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
mLastCameraQuery.fovPort[0] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[0], mLastCameraQuery);
mLastCameraQuery.fovPort[1] = CalculateFovPortForCanvas(mLastCameraQuery.stereoViewports[1], mLastCameraQuery);
}
GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes
GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes
GFX->setSteroViewports(mLastCameraQuery.stereoViewports);
GFX->setStereoTargets(mLastCameraQuery.stereoTargets);
MatrixF myTransforms[2];
Frustum frustum;
if (smUseLatestDisplayTransform)
{
@ -435,52 +515,109 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
renderSize = mLastCameraQuery.stereoViewports[0].extent;
renderingToTarget = true;
}
}
else
{
GFX->setCurrentRenderStyle(GFXDevice::RS_Standard);
}
if ( mReflectPriority > 0 )
{
// Get the total reflection priority.
F32 totalPriority = 0;
for ( U32 i=0; i < smAwakeTSCtrls.size(); i++ )
if ( smAwakeTSCtrls[i]->isVisible() )
totalPriority += smAwakeTSCtrls[i]->mReflectPriority;
REFLECTMGR->update( mReflectPriority / totalPriority,
getExtent(),
mLastCameraQuery );
}
if(mForceFOV != 0)
mLastCameraQuery.fov = mDegToRad(mForceFOV);
if(mCameraZRot)
{
MatrixF rotMat(EulerF(0, 0, mDegToRad(mCameraZRot)));
mLastCameraQuery.cameraMatrix.mul(rotMat);
}
Frustum frustum;
if(mRenderStyle == RenderStyleStereoSideBySide)
{
// NOTE: these calculations are essentially overridden later by the fov port settings when rendering each eye.
MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
GFX->activateStereoTarget(-1);
_internalRender(RectI(updateRect.point, updateRect.extent), frustum);
// Render preview
if (mLastCameraQuery.displayDevice)
{
GFXTexHandle previewTexture = mLastCameraQuery.displayDevice->getPreviewTexture();
if (!previewTexture.isNull())
{
GFX->setActiveRenderTarget(origTarget);
GFX->setCurrentRenderStyle(origStyle);
GFX->setClipRect(updateRect);
renderDisplayPreview(updateRect, previewTexture);
}
}
}
else if (mRenderStyle == RenderStyleStereoSeparate && mLastCameraQuery.stereoTargets[0])
{
// In this case we render the scene twice to different render targets, then
// render the final composite view
GFX->setCurrentRenderStyle(GFXDevice::RS_StereoSeparate);
GFX->setStereoEyeOffsets(mLastCameraQuery.eyeOffset);
GFX->setStereoFovPort(mLastCameraQuery.fovPort); // NOTE: this specifies fov for BOTH eyes
GFX->setSteroViewports(mLastCameraQuery.stereoViewports);
GFX->setStereoTargets(mLastCameraQuery.stereoTargets);
MatrixF myTransforms[2];
if (smUseLatestDisplayTransform)
{
// Use the view matrix determined from the display device
myTransforms[0] = mLastCameraQuery.eyeTransforms[0];
myTransforms[1] = mLastCameraQuery.eyeTransforms[1];
}
else
{
// Use the view matrix determined from the control object
myTransforms[0] = mLastCameraQuery.cameraMatrix;
myTransforms[1] = mLastCameraQuery.cameraMatrix;
QuatF qrot = mLastCameraQuery.cameraMatrix;
Point3F pos = mLastCameraQuery.cameraMatrix.getPosition();
Point3F rotEyePos;
myTransforms[0].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[0], &rotEyePos));
myTransforms[1].setPosition(pos + qrot.mulP(mLastCameraQuery.eyeOffset[1], &rotEyePos));
}
MatrixF origMatrix = mLastCameraQuery.cameraMatrix;
// Left
MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[0]);
mLastCameraQuery.cameraMatrix = myTransforms[0];
frustum.update();
GFX->activateStereoTarget(0);
_internalRender(RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[0]->getSize()), frustum);
GFX->getDeviceEventSignal().trigger(GFXDevice::deLeftStereoFrameRendered);
// Right
GFX->activateStereoTarget(1);
MathUtils::makeFovPortFrustum(&frustum, mLastCameraQuery.ortho, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane, mLastCameraQuery.fovPort[1]);
mLastCameraQuery.cameraMatrix = myTransforms[1];
frustum.update();
_internalRender(RectI(Point2I(0, 0), mLastCameraQuery.stereoTargets[1]->getSize()), frustum);
GFX->getDeviceEventSignal().trigger(GFXDevice::deRightStereoFrameRendered);
mLastCameraQuery.cameraMatrix = origMatrix;
// Render preview
if (mLastCameraQuery.displayDevice)
{
GFXTexHandle previewTexture = mLastCameraQuery.displayDevice->getPreviewTexture();
if (!previewTexture.isNull())
{
GFX->setActiveRenderTarget(origTarget);
GFX->setCurrentRenderStyle(origStyle);
GFX->setClipRect(updateRect);
renderDisplayPreview(updateRect, previewTexture);
}
}
}
else
{
#ifdef TORQUE_OS_MAC
Point2I screensize = getRoot()->getWindowSize();
tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
#endif
GFX->setCurrentRenderStyle(GFXDevice::RS_Standard);
// set up the camera and viewport stuff:
F32 wwidth;
F32 wheight;
F32 renderWidth = F32(renderSize.x);
F32 renderHeight = F32(renderSize.y);
F32 aspectRatio = renderWidth / renderHeight;
// Use the FOV to calculate the viewport height scale
// then generate the width scale from the aspect ratio.
if(!mLastCameraQuery.ortho)
if (!mLastCameraQuery.ortho)
{
wheight = mLastCameraQuery.nearPlane * mTan(mLastCameraQuery.fov / 2.0f);
wwidth = aspectRatio * wheight;
@ -499,251 +636,33 @@ void GuiTSCtrl::onRender(Point2I offset, const RectI &updateRect)
F32 top = wheight - vscale * (updateRect.point.y - offset.y);
F32 bottom = wheight - vscale * (updateRect.point.y + updateRect.extent.y - offset.y);
frustum.set( mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane );
}
frustum.set(mLastCameraQuery.ortho, left, right, top, bottom, mLastCameraQuery.nearPlane, mLastCameraQuery.farPlane);
// Manipulate the frustum for tiled screenshots
const bool screenShotMode = gScreenShot && gScreenShot->isPending();
if ( screenShotMode )
{
gScreenShot->tileFrustum( frustum );
GFX->setViewMatrix(MatrixF::Identity);
}
RectI tempRect = updateRect;
if (!renderingToTarget)
{
#ifdef TORQUE_OS_MAC
// Manipulate the frustum for tiled screenshots
const bool screenShotMode = gScreenShot && gScreenShot->isPending();
if (screenShotMode)
{
gScreenShot->tileFrustum(frustum);
GFX->setViewMatrix(MatrixF::Identity);
}
RectI tempRect = updateRect;
#ifdef TORQUE_OS_MAC
Point2I screensize = getRoot()->getWindowSize();
tempRect.point.y = screensize.y - (tempRect.point.y + tempRect.extent.y);
#endif
#endif
GFX->setViewport( tempRect );
}
else
{
// Activate stereo RT
GFX->activateStereoTarget(-1);
_internalRender(tempRect, frustum);
}
// Clear the zBuffer so GUI doesn't hose object rendering accidentally
GFX->clear( GFXClearZBuffer , ColorI(20,20,20), 1.0f, 0 );
//GFX->clear( GFXClearTarget, ColorI(255,0,0), 1.0f, 0);
GFX->setFrustum( frustum );
if(mLastCameraQuery.ortho)
{
mOrthoWidth = frustum.getWidth();
mOrthoHeight = frustum.getHeight();
}
// We're going to be displaying this render at size of this control in
// pixels - let the scene know so that it can calculate e.g. reflections
// correctly for that final display result.
gClientSceneGraph->setDisplayTargetResolution(renderSize);
// Set the GFX world matrix to the world-to-camera transform, but don't
// change the cameraMatrix in mLastCameraQuery. This is because
// mLastCameraQuery.cameraMatrix is supposed to contain the camera-to-world
// transform. In-place invert would save a copy but mess up any GUIs that
// depend on that value.
MatrixF worldToCamera = mLastCameraQuery.cameraMatrix;
worldToCamera.inverse();
GFX->setWorldMatrix( worldToCamera );
mSaveProjection = GFX->getProjectionMatrix();
mSaveModelview = GFX->getWorldMatrix();
mSaveViewport = updateRect;
mSaveWorldToScreenScale = GFX->getWorldToScreenScale();
mSaveFrustum = GFX->getFrustum();
mSaveFrustum.setTransform( mLastCameraQuery.cameraMatrix );
// Set the default non-clip projection as some
// objects depend on this even in non-reflect cases.
gClientSceneGraph->setNonClipProjection( mSaveProjection );
// Give the post effect manager the worldToCamera, and cameraToScreen matrices
PFXMGR->setFrameMatrices( mSaveModelview, mSaveProjection );
renderWorld(updateRect);
DebugDrawer::get()->render();
// Render the canvas overlay if its available
if (false && mRenderStyle == RenderStyleStereoSideBySide && mStereoGuiTarget.getPointer())
{
GFXDEBUGEVENT_SCOPE( StereoGui_Render, ColorI( 255, 0, 0 ) );
MatrixF proj(1);
Frustum originalFrustum = GFX->getFrustum();
GFXTextureObject *texObject = mStereoGuiTarget->getTexture(0);
const FovPort *currentFovPort = GFX->getStereoFovPort();
const MatrixF *eyeTransforms = GFX->getStereoEyeTransforms();
const Point3F *eyeOffset = GFX->getStereoEyeOffsets();
Frustum gfxFrustum = originalFrustum;
for (U32 i=0; i<2; i++)
{
GFX->activateStereoTarget(i);
MathUtils::makeFovPortFrustum(&gfxFrustum, true, gfxFrustum.getNearDist(), gfxFrustum.getFarDist(), currentFovPort[i], eyeTransforms[i]);
GFX->setFrustum(gfxFrustum);
MatrixF eyeWorldTrans(1);
eyeWorldTrans.setPosition(Point3F(eyeOffset[i].x,eyeOffset[i].y,eyeOffset[i].z));
MatrixF eyeWorld(1);
eyeWorld.mul(eyeWorldTrans);
eyeWorld.inverse();
GFX->setWorldMatrix(eyeWorld);
GFX->setViewMatrix(MatrixF::Identity);
if (!mStereoOverlayVB.getPointer())
{
mStereoOverlayVB.set(GFX, 4, GFXBufferTypeStatic);
GFXVertexPCT *verts = mStereoOverlayVB.lock(0, 4);
F32 texLeft = 0.0f;
F32 texRight = 1.0f;
F32 texTop = 1.0f;
F32 texBottom = 0.0f;
F32 rectRatio = gfxFrustum.getWidth() / gfxFrustum.getHeight();
F32 rectWidth = gfxFrustum.getWidth() * TS_OVERLAY_SCREEN_WIDTH;
F32 rectHeight = rectWidth * rectRatio;
F32 screenLeft = -rectWidth * 0.5;
F32 screenRight = rectWidth * 0.5;
F32 screenTop = -rectHeight * 0.5;
F32 screenBottom = rectHeight * 0.5;
const F32 fillConv = 0.0f;
const F32 frustumDepthAdjusted = gfxFrustum.getNearDist() + 0.012;
verts[0].point.set( screenLeft - fillConv, frustumDepthAdjusted, screenTop - fillConv );
verts[1].point.set( screenRight - fillConv, frustumDepthAdjusted, screenTop - fillConv );
verts[2].point.set( screenLeft - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
verts[3].point.set( screenRight - fillConv, frustumDepthAdjusted, screenBottom - fillConv );
verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255);
verts[0].texCoord.set( texLeft, texTop );
verts[1].texCoord.set( texRight, texTop );
verts[2].texCoord.set( texLeft, texBottom );
verts[3].texCoord.set( texRight, texBottom );
mStereoOverlayVB.unlock();
}
if (!mStereoGuiSB.getPointer())
{
// DrawBitmapStretchSR
GFXStateBlockDesc bitmapStretchSR;
bitmapStretchSR.setCullMode(GFXCullNone);
bitmapStretchSR.setZReadWrite(false, false);
bitmapStretchSR.setBlend(false , GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
bitmapStretchSR.samplersDefined = true;
bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear();
bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint;
bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint;
bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint;
mStereoGuiSB = GFX->createStateBlock(bitmapStretchSR);
}
GFX->setVertexBuffer(mStereoOverlayVB);
GFX->setStateBlock(mStereoGuiSB);
GFX->setTexture( 0, texObject );
GFX->setupGenericShaders( GFXDevice::GSModColorTexture );
GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
}
}
// Restore the previous matrix state before
// we begin rendering the child controls.
saver.restore();
// Restore the render style and any stereo parameters
GFX->setActiveRenderTarget(origTarget);
GFX->setCurrentRenderStyle(prevRenderStyle);
GFX->setCurrentProjectionOffset(prevProjectionOffset);
GFX->updateStates(true);
if(mRenderStyle == RenderStyleStereoSideBySide && gLastStereoTexture)
{
GFX->setWorldMatrix(MatrixF(1));
GFX->setViewMatrix(MatrixF::Identity);
GFX->setClipRect(updateRect);
GFX->getDrawUtil()->drawRectFill(RectI(Point2I(0,0), Point2I(1024, 768)), ColorI::BLACK);
GFX->getDrawUtil()->drawRect(RectI(Point2I(0, 0), Point2I(1024, 768)), ColorI::RED);
if (!mStereoOverlayVB.getPointer())
{
mStereoOverlayVB.set(GFX, 4, GFXBufferTypeStatic);
GFXVertexPCT *verts = mStereoOverlayVB.lock(0, 4);
F32 texLeft = 0.0f;
F32 texRight = 1.0f;
F32 texTop = 1.0f;
F32 texBottom = 0.0f;
F32 rectWidth = 1024.0;
F32 rectHeight = 768.0;
F32 screenLeft = 0;
F32 screenRight = rectWidth;
F32 screenTop = 0;
F32 screenBottom = rectHeight;
const F32 fillConv = 0.0f;
const F32 frustumDepthAdjusted = 0.0f;
verts[0].point.set(screenLeft - fillConv, screenTop - fillConv, 0.f);
verts[1].point.set(screenRight - fillConv, screenTop - fillConv, 0.f);
verts[2].point.set(screenLeft - fillConv, screenBottom - fillConv, 0.f);
verts[3].point.set(screenRight - fillConv, screenBottom - fillConv, 0.f);
verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255,255,255,255);
verts[0].texCoord.set(texLeft, texTop);
verts[1].texCoord.set(texRight, texTop);
verts[2].texCoord.set(texLeft, texBottom);
verts[3].texCoord.set(texRight, texBottom);
mStereoOverlayVB.unlock();
}
if (!mStereoGuiSB.getPointer())
{
// DrawBitmapStretchSR
GFXStateBlockDesc bitmapStretchSR;
bitmapStretchSR.setCullMode(GFXCullNone);
bitmapStretchSR.setZReadWrite(false, false);
bitmapStretchSR.setBlend(false, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
bitmapStretchSR.samplersDefined = true;
bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear();
bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint;
bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint;
bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint;
mStereoGuiSB = GFX->createStateBlock(bitmapStretchSR);
}
//static GFXTexHandle texHandle("art/gui/splash", &GFXDefaultPersistentProfile, avar("%s() - mTextureNormal (line %d)", __FUNCTION__, __LINE__));
GFX->setVertexBuffer(mStereoOverlayVB);
GFX->setStateBlock(mStereoGuiSB);
GFX->setTexture(0, gLastStereoTexture);// texHandle);// gLastStereoTexture);
GFX->setupGenericShaders(GFXDevice::GSModColorTexture);
GFX->drawPrimitive(GFXTriangleStrip, 0, 2);
//GFX->getDrawUtil()->drawBitmapStretch(gLastStereoTexture, updateRect);
}
// TODO: Some render to sort of overlay system?
// Allow subclasses to render 2D elements.
GFX->setActiveRenderTarget(origTarget);
GFX->setCurrentRenderStyle(origStyle);
GFX->setClipRect(updateRect);
renderGui( offset, updateRect );
renderGui(offset, updateRect);
if (shouldRenderChildControls())
{
@ -779,12 +698,84 @@ void GuiTSCtrl::drawLineList( const Vector<Point3F> &points, const ColorI color,
drawLine( points[i], points[i+1], color, width );
}
//-----------------------------------------------------------------------------
void GuiTSCtrl::setStereoGui(GuiOffscreenCanvas *canvas)
{
mStereoGuiTarget = canvas ? canvas->getTarget() : NULL;
}
//-----------------------------------------------------------------------------
void GuiTSCtrl::renderDisplayPreview(const RectI &updateRect, GFXTexHandle &previewTexture)
{
GFX->setWorldMatrix(MatrixF(1));
GFX->setViewMatrix(MatrixF::Identity);
GFX->setClipRect(updateRect);
GFX->getDrawUtil()->drawRectFill(RectI(Point2I(0, 0), Point2I(1024, 768)), ColorI::BLACK);
GFX->getDrawUtil()->drawRect(RectI(Point2I(0, 0), Point2I(1024, 768)), ColorI::RED);
if (!mStereoPreviewVB.getPointer())
{
mStereoPreviewVB.set(GFX, 4, GFXBufferTypeStatic);
GFXVertexPCT *verts = mStereoPreviewVB.lock(0, 4);
F32 texLeft = 0.0f;
F32 texRight = 1.0f;
F32 texTop = 0.0f;
F32 texBottom = 1.0f;
F32 rectWidth = updateRect.extent.x;
F32 rectHeight = updateRect.extent.y;
F32 screenLeft = 0;
F32 screenRight = rectWidth;
F32 screenTop = 0;
F32 screenBottom = rectHeight;
const F32 fillConv = 0.0f;
const F32 frustumDepthAdjusted = 0.0f;
verts[0].point.set(screenLeft - fillConv, screenTop - fillConv, 0.f);
verts[1].point.set(screenRight - fillConv, screenTop - fillConv, 0.f);
verts[2].point.set(screenLeft - fillConv, screenBottom - fillConv, 0.f);
verts[3].point.set(screenRight - fillConv, screenBottom - fillConv, 0.f);
verts[0].color = verts[1].color = verts[2].color = verts[3].color = ColorI(255, 255, 255, 255);
verts[0].texCoord.set(texLeft, texTop);
verts[1].texCoord.set(texRight, texTop);
verts[2].texCoord.set(texLeft, texBottom);
verts[3].texCoord.set(texRight, texBottom);
mStereoPreviewVB.unlock();
}
if (!mStereoPreviewSB.getPointer())
{
// DrawBitmapStretchSR
GFXStateBlockDesc bitmapStretchSR;
bitmapStretchSR.setCullMode(GFXCullNone);
bitmapStretchSR.setZReadWrite(false, false);
bitmapStretchSR.setBlend(false, GFXBlendSrcAlpha, GFXBlendInvSrcAlpha);
bitmapStretchSR.samplersDefined = true;
bitmapStretchSR.samplers[0] = GFXSamplerStateDesc::getClampLinear();
bitmapStretchSR.samplers[0].minFilter = GFXTextureFilterPoint;
bitmapStretchSR.samplers[0].mipFilter = GFXTextureFilterPoint;
bitmapStretchSR.samplers[0].magFilter = GFXTextureFilterPoint;
mStereoPreviewSB = GFX->createStateBlock(bitmapStretchSR);
}
GFX->setVertexBuffer(mStereoPreviewVB);
GFX->setStateBlock(mStereoPreviewSB);
GFX->setTexture(0, previewTexture);
GFX->setupGenericShaders(GFXDevice::GSModColorTexture);
GFX->drawPrimitive(GFXTriangleStrip, 0, 2);
}
//=============================================================================
// Console Methods.
//=============================================================================