Exemplo n.º 1
0
/**
* Updates left and right projection matrices.
* Now, the convergence point is specified in real, physical meters, since the IPD is also specified
* in physical meters. That means, if the game-specific world scale is set correctly, a convergence
* value of 3.0f would mean that the virtual screen, neutral point or convergence point is 3 meters
* ahead of us.
* @param aspectRation The aspect ratio for the projection matrix.
***/
void ViewAdjustment::UpdateProjectionMatrices(float aspectRatio)
{
	t = 0.5f / aspectRatio;
	b = -0.5f / aspectRatio;

	D3DXMatrixPerspectiveOffCenterLH(&matProjection, l, r, b, t, n, f);
	D3DXMatrixInverse(&matProjectionInv, 0, &matProjection);

	// ALL stated in meters here ! screen size = horizontal size
	float nearClippingPlaneDistance = hmdInfo.eyeToScreenDistance; 
	float physicalScreenSizeInMeters = hmdInfo.physicalScreenSize.first / 2; 

	// if not HMD, set values to fullscreen defaults
	if ((stereoType != 26) && // != StereoView::StereoTypes::OCULUS_RIFT
		(stereoType != 27) && // != StereoView::StereoTypes::OCULUS_RIFT_CROPPED
		(stereoType != 25))   // != StereoView::StereoTypes::DIY_RIFT))
	{
		// assumption here :
		// end user is placed 1 meter away from screen
		// end user screen is 1 meter in horizontal size
		nearClippingPlaneDistance = 1;
		physicalScreenSizeInMeters = 1;
	}

	// convergence frustum adjustment, based on NVidia explanations
	//
	// It is evident that the ratio of frustum shift to the near clipping plane is equal to the ratio of 
	// IOD/2 to the distance from the screenplane. (IOD=IPD) 
	// frustumAsymmetryInMeters = ((IPD/2) * nearClippingPlaneDistance) / convergence
	// <http://www.orthostereo.com/geometryopengl.html>
	//
	// (near clipping plane distance = physical screen distance)
	// (convergence = virtual screen distance)
	if (convergence <= nearClippingPlaneDistance) convergence = nearClippingPlaneDistance + 0.001f;
	float frustumAsymmetryInMeters = ((ipd/2) * nearClippingPlaneDistance) / convergence;

	// divide the frustum asymmetry by the assumed physical size of the physical screen
	float frustumAsymmetryLeftInMeters = (frustumAsymmetryInMeters * LEFT_CONSTANT) / physicalScreenSizeInMeters;
	float frustumAsymmetryRightInMeters = (frustumAsymmetryInMeters * RIGHT_CONSTANT) / physicalScreenSizeInMeters;

	// get the horizontal screen space size and compute screen space adjustment
	float screenSpaceXSize = abs(l)+abs(r);
	float multiplier = screenSpaceXSize/1; // = 1 meter
	float frustumAsymmetryLeft = frustumAsymmetryLeftInMeters * multiplier;
	float frustumAsymmetryRight = frustumAsymmetryRightInMeters * multiplier;

	// now, create the re-projection matrices for both eyes using this frustum asymmetry
	D3DXMatrixPerspectiveOffCenterLH(&projectLeft, l+frustumAsymmetryLeft, r+frustumAsymmetryLeft, b, t, n, f);
	D3DXMatrixPerspectiveOffCenterLH(&projectRight, l+frustumAsymmetryRight, r+frustumAsymmetryRight, b, t, n, f);
}
Exemplo n.º 2
0
void Window::setProjection(vrj::ProjectionPtr proj)
{
   if (!mWindowIsOpen)
   {
      return;
   }

   const std::vector<float>& frust = proj->getFrustum().getValues();

   D3DXMATRIX proj_matrix;
   ZeroMemory( &proj_matrix, sizeof( D3DXMATRIX ) );

   D3DXMatrixPerspectiveOffCenterLH(&proj_matrix,
      frust[Frustum::VJ_LEFT], frust[Frustum::VJ_RIGHT],
      frust[Frustum::VJ_BOTTOM], frust[Frustum::VJ_TOP],
      frust[Frustum::VJ_NEAR], frust[Frustum::VJ_FAR]);

   mRenderDevice->SetTransform( D3DTS_PROJECTION, &proj_matrix );
#ifdef USE_PROJECTION_MATRIX
   mRenderDevice->MultiplyTransform( D3DTS_PROJECTION, (const D3DMATRIX*)&proj->getViewMatrix().mData);
#endif

#ifndef USE_PROJECTION_MATRIX
   D3DXMATRIX view_matrix;
   D3DXMatrixIdentity(view_matrix);
   mRenderDevice->SetTransform(D3DTS_VIEW, &view_matrix);
   mRenderDevice->MultiplyTransform( D3DTS_VIEW, &proj->getViewMatrix().mData);
#endif
}
Exemplo n.º 3
0
void D3DProxyDeviceAdv::adjustEyeOffsetAndViewFrustum(D3DXMATRIX &outMatrix, D3DXMATRIX &inMatrix)
{
	D3DXMATRIX transform;
	D3DXMatrixTranslation(&transform, separation*eyeShutter*10.0f+offset*10.0f, 0, 0);

	float adjustedFrustumOffset = convergence*eyeShutter*0.1f;		
	D3DXMATRIX reProject;
	D3DXMatrixPerspectiveOffCenterLH(&reProject, l+adjustedFrustumOffset, r+adjustedFrustumOffset, b, t, n, f);

	if(trackerInitialized && tracker->isAvailable())
	{
		D3DXMATRIX rollMatrix;
		D3DXMatrixRotationZ(&rollMatrix, tracker->currentRoll);
		D3DXMatrixMultiply(&transform, &transform, &rollMatrix);
	}

	outMatrix = inMatrix * invertProjection * transform * reProject;
}
Exemplo n.º 4
0
//-- Render -------------------------------------------------------------------
// Called once per frame. Do all rendering here.
//-----------------------------------------------------------------------------
extern "C" void Render()
{
  bool configured = true; //FALSE;

  g_device->SetRenderState(D3DRS_SRCBLEND , D3DBLEND_ONE);
  g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO);
  g_device->SetRenderState(D3DRS_AMBIENT, 0xffffffff);
  g_device->SetRenderState(D3DRS_LIGHTING, FALSE);
  g_device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
  g_device->SetRenderState(D3DRS_ZENABLE, TRUE);
  g_device->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
  g_device->SetRenderState(D3DRS_ZFUNC, D3DCMP_LESS);
  g_device->SetRenderState(D3DRS_FILLMODE, g_mode);
  g_device->SetFVF(VERTEX_FORMAT);
  g_device->SetPixelShader(NULL);
  g_device->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DXCOLOR(0.0f, 0.0f, 0.0f, 0.0f), 1.0f, 0);

  D3DXMATRIX matProjection;
  D3DXMatrixPerspectiveOffCenterLH(&matProjection, -1.0f, 1.0f, -1.0f, 1.0f, 1.5f, 10.0f);
  g_device->SetTransform(D3DTS_PROJECTION, &matProjection);

  D3DXMATRIX matView;
  D3DXMatrixIdentity(&matView);
  g_device->SetTransform(D3DTS_VIEW, &matView);

  if(configured)
  {
    x_angle += x_speed;
    if(x_angle >= 360.0f)
      x_angle -= 360.0f;

    y_angle += y_speed;
    if(y_angle >= 360.0f)
      y_angle -= 360.0f;

    z_angle += z_speed;
    if(z_angle >= 360.0f)
      z_angle -= 360.0f;

    draw_bars();
  }
}
Exemplo n.º 5
0
void Storm3D_SpotlightShared::updateMatricesOffCenter(const D3DXMATRIX &cameraView, const VC2 &min, const VC2 &max, float height, Storm3D_Camera &camera)
{
	// Position of the light in global coordinates
	// Y-axis is height
	D3DXVECTOR3 lightPosition(position.x, position.y, position.z);
	// Up vector (z-axis)
	D3DXVECTOR3 up(0.f, 0.f, 1.f);
	// Look direction
	D3DXVECTOR3 lookAt = lightPosition;
	lookAt.y -= 1.f;

	{
		// max and min define the extents of light area in local coordinates
		// Z-axis is height
		float zmin = 0.2f;
		//float zmax = std::max(range, height) * 1.4f;
		// height is light height from light properties
		float zmax = height;
		float factor = 1.5f * zmin / height;
		float xmin = min.x * factor;
		float xmax = max.x * factor;
		float ymin = min.y * factor;
		float ymax = max.y * factor;
		D3DXMatrixPerspectiveOffCenterLH(&lightProjection, xmin, xmax, ymin, ymax, zmin, zmax);

		// Calculate the extents of light area in global coordinates
		VC2 worldMin = min;
		worldMin.x += position.x;
		worldMin.y += position.z;
		VC2 worldMax = max;
		worldMax.x += position.x;
		worldMax.y += position.z;

		// Generate approximate camera for culling.

		// Calculate range of the camera.
		// Y-axis is height
		float planeY = position.y - height;
		// Calculate distances from light position to light plane edges
		VC3 p1 = VC3( worldMin.x, planeY, worldMin.y ) - position;
		VC3 p2 = VC3( worldMax.x, planeY, worldMin.y ) - position;
		VC3 p3 = VC3( worldMax.x, planeY, worldMax.y ) - position;
		VC3 p4 = VC3( worldMin.x, planeY, worldMax.y ) - position;
		float d1 = p1.GetLength();
		float d2 = p2.GetLength();
		float d3 = p3.GetLength();
		float d4 = p4.GetLength();
		float maxRange = 0.0f;
		maxRange = MAX( maxRange, d1 );
		maxRange = MAX( maxRange, d2 );
		maxRange = MAX( maxRange, d3 );
		maxRange = MAX( maxRange, d4 );
		//maxRange = sqrtf(maxRange);

		// Calculate FOV of the camera.
		VC3 planeCenter = VC3( (worldMin.x + worldMax.x) * 0.5f, planeY, (worldMin.y + worldMax.y) * 0.5f );
		VC3 camVec = planeCenter - position;
		camVec.Normalize();
		float minDot = 10000.0f;
		float t1 = camVec.GetDotWith( p1 ) / d1;
		float t2 = camVec.GetDotWith( p2 ) / d2;
		float t3 = camVec.GetDotWith( p3 ) / d3;
		float t4 = camVec.GetDotWith( p4 ) / d4;
		minDot = MIN( minDot, t1 );
		minDot = MIN( minDot, t2 );
		minDot = MIN( minDot, t3 );
		minDot = MIN( minDot, t4 );
		float maxAngle = acosf( minDot );

		// Place camera to light position
		camera.SetPosition(position);
		camera.SetUpVec(VC3(0.f, 0.f, 1.f));
		// Point camera at light plane center
		camera.SetTarget(planeCenter);
		camera.SetFieldOfView( maxAngle );
		camera.SetVisibilityRange( maxRange );
	}
	
	D3DXMATRIX cameraMatrix(cameraView);
	float det = D3DXMatrixDeterminant(&cameraMatrix);
	D3DXMatrixInverse(&cameraMatrix, &det, &cameraMatrix);

	unsigned int tweakRange = 1;
	float bias = 0.f;
	float currentBias = 0.f;
	for(int i = 0; i < 2; ++i)
	{	
		D3DXMatrixLookAtLH(&lightView[i], &lightPosition, &lookAt, &up);
		if(i == 1)
			currentBias = 0;

		// Tweak matrix
		float soffsetX = 0.5f;
		float soffsetY = 0.5f;
		float scale = 0.5f;

		D3DXMATRIX shadowTweak( scale,    0.0f,     0.0f,				0.0f,
								0.0f,     -scale,   0.0f,				0.0f,
								0.0f,      0.0f,     float(tweakRange),	0.0f,
								soffsetX,  soffsetY, currentBias,		1.0f );

		D3DXMatrixMultiply(&shadowProjection[i], &lightProjection, &shadowTweak);
		D3DXMatrixMultiply(&shadowProjection[i], &lightView[i], &shadowProjection[i]);
		D3DXMatrixMultiply(&lightViewProjection[i], &lightView[i], &lightProjection);

		shaderProjection[i] = shadowProjection[i];
		D3DXMatrixMultiply(&shadowProjection[i], &cameraMatrix, &shadowProjection[i]);
	}

	{
		float xf = (1.f / resolutionX * .5f);
		float yf = (1.f / resolutionY * .5f);
		float sX = soffsetX + (2 * targetPos.x * soffsetX) - xf;
		float sY = soffsetY + (2 * targetPos.y * soffsetY) - yf;

		D3DXMATRIX shadowTweak( scaleX,    0.0f,	0.0f,				0.0f,
								0.0f,    -scaleY,	0.0f,				0.0f,
								0.0f,     0.0f,     float(tweakRange),	0.0f,
								sX,       sY,		bias,				1.0f );

		D3DXMatrixMultiply(&targetProjection, &lightProjection, &shadowTweak);
		D3DXMatrixMultiply(&targetProjection, &lightView[0], &targetProjection);
	}
}