⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mvolumerender.cpp

📁 virtual reality project. This algorithm for building large image to Volume rendering. Using directx
💻 CPP
📖 第 1 页 / 共 5 页
字号:
	// make linear otf array
	makeOtf();

	HRESULT hr;

   // Fill pre-integrated texture
     	// make 
		preIntegratedArray[0][0][0] = m_linearOtfArray[0];
		preIntegratedArray[0][0][1] = m_linearOtfArray[0];
	
	//	float tmpAlpha = m_linearOtfArray[0]/255.0f;
	//	summedTable[0][0] = m_linearOtfArray[0] * tmpAlpha;  // for RGB
		summedTable[0][0] = (float)m_linearOtfArray[0];  // for RGB
		summedTable[0][1] = (float)m_linearOtfArray[0];  // for alpha

		for(int d=1; d<OTFTEXTUREWIDTH; d++) {
			preIntegratedArray[d][d][0] = m_linearOtfArray[d];
			preIntegratedArray[d][d][1] = m_linearOtfArray[d];
	//		tmpAlpha = m_linearOtfArray[d]/255.0f;
	//		summedTable[d][0] = summedTable[d-1][0] + m_linearOtfArray[d]*tmpAlpha;  // for RGB
			summedTable[d][0] = summedTable[d-1][0] + m_linearOtfArray[d];  // for RGB
			summedTable[d][1] = summedTable[d-1][1] + m_linearOtfArray[d];  // for alpha
		}
	
		//
		for(int sBack = 0; sBack < OTFTEXTUREWIDTH ; sBack++) {
			int div = 0;
			for(int sFront = sBack+1; sFront < OTFTEXTUREWIDTH; sFront++) {
				div++;
				preIntegratedArray[sBack][sFront][0] = DWORD((summedTable[sFront][0] - summedTable[sBack][0]) / (float)div);
				preIntegratedArray[sBack][sFront][1] = DWORD((summedTable[sFront][1] - summedTable[sBack][1]) / (float)div);
			}
		}
		// Upper-left copy
		for(int sFront = 0; sFront < OTFTEXTUREWIDTH ; sFront++) {
			for(int sBack = sFront+1; sBack < OTFTEXTUREWIDTH; sBack++) {
				preIntegratedArray[sBack][sFront][0] = preIntegratedArray[sFront][sBack][0];
				preIntegratedArray[sBack][sFront][1] = preIntegratedArray[sFront][sBack][1];
			}
		}

		D3DLOCKED_RECT LockedRect;
		hr = m_pPreIntegratedTexture->LockRect( 0, &LockedRect, 0, D3DLOCK_DISCARD);
        if( FAILED(hr) )
            return hr;
		
		// yellow color
		DWORD a, r, g, b;
		#define OTFRED    255
		#define OTFGREEN  255
		#define OTFBLUE   255//159

		for( UINT v=0; v<OTFTEXTUREWIDTH; v++ )  {
            for( UINT u=0; u<OTFTEXTUREWIDTH; u++ )  {
				r = preIntegratedArray[v][u][0];
				g = preIntegratedArray[v][u][0];
				b = preIntegratedArray[v][u][0];
				a = preIntegratedArray[v][u][1];
//				float tempDiv = (a / 255.0f);

				//-----------------------------------------------------------------
				/*
				//for Opacity Weighted interpolation (color 俊 alpha 蚌秦辑 持绢淋.)???
				// 咯扁辑 窍绰霸 唱篮瘤, 利盒窍扁傈俊 蚌秦辑 利盒窍绰霸 唱篮瘤?...
				r = DWORD(OTFRED * tempDiv);
				g = DWORD(OTFGREEN * tempDiv);
				b = DWORD(OTFBLUE * tempDiv);
				*/
				((DWORD*)LockedRect.pBits)[u] = 0x00000000 + (a<<24) + (r<<16) + (g<<8) + (b);
            }
			LockedRect.pBits = (BYTE*)LockedRect.pBits + LockedRect.Pitch;
        }

        m_pPreIntegratedTexture->UnlockRect( 0 );

	return TRUE;
}


//////////////////////// make(update) Min Max Volume texture //////////////////
//-----   called in InitDeviceObjects(), OnHScroll() --------------------------------
HRESULT CAppForm::makeMMVolumeTexture()
{
	HRESULT hr;
		D3DLOCKED_BOX LockedBox;
		hr = m_pVolumeTexMM->LockBox(0, &LockedBox, 0, 0);
			if( FAILED(hr) )
				return FALSE;
					
		for(int w=0; w<divZ; w++ )
		{   
			BYTE* pSliceStart = (BYTE*)LockedBox.pBits;
			for(int v=0; v<divY; v++ )
			{
				for(int u=0; u<divX; u++ )
				{
					BYTE nonEmpty = 255; 

					int scalarMin = int(minDenDiv8[u][v][w] / float(0xffff) * (OTFTEXTUREWIDTH-1));
					int scalarMax = int(maxDenDiv8[u][v][w] / float(0xffff) * (OTFTEXTUREWIDTH-1));

					if( scalarMin >= OTFTEXTUREWIDTH ) scalarMin = OTFTEXTUREWIDTH - 1;
					if( scalarMax >= OTFTEXTUREWIDTH ) scalarMax = OTFTEXTUREWIDTH - 1;

					if( preIntegratedArray[scalarMin][scalarMax][1] == 0 ) { // preInt alpha 啊 0 搁..
						nonEmpty = 0;
					}
																
					((BYTE*)LockedBox.pBits)[u] = nonEmpty;
					}
				LockedBox.pBits = (BYTE*)LockedBox.pBits + LockedBox.RowPitch;
			}
			LockedBox.pBits = pSliceStart + LockedBox.SlicePitch;
		}//end of for
												
		m_pVolumeTexMM->UnlockBox(0);

	return TRUE;
}



////////////////// make HLSL Effect shader() ///////////////////////////////////////
//-----   called in InitDeviceObjects()  --------------------------------------
HRESULT CAppForm::MCreateShader()
{
	HRESULT hr;
	D3DCAPS9 caps;
	m_pd3dDevice->GetDeviceCaps(&caps);    // initialize m_pd3dDevice before using
	if( caps.VertexShaderVersion < D3DVS_VERSION(2,0) )
		return E_FAIL;

	// Create the shader declaration for pass0.
	D3DVERTEXELEMENT9 declPass0Proxy[] = 
	{
		{ 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
		{ 0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
		D3DDECL_END()
	};	
	if( FAILED( hr = m_pd3dDevice->CreateVertexDeclaration( declPass0Proxy, &m_pObjOrderProxyVertexDecl ) ) )
        return hr;

	// Create the shader declaration for pass1.
	D3DVERTEXELEMENT9 declPass1Proxy[] = 
	{
		{ 0, 0,  D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 },
		{ 0, 12, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
		{ 0, 24, D3DDECLTYPE_FLOAT3,   D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
		D3DDECL_END()
	};	
	if( FAILED( hr = m_pd3dDevice->CreateVertexDeclaration( declPass1Proxy, &m_pImagOrderProxyVertexDecl ) ) )
        return hr;

	//------------ make effect shader ----------------------------
	// D3DXSHADER_PACKMATRIX_COLUMNMAJOR (DEFAULT) 荤侩.
	hr = D3DXCreateEffectFromFile(m_pd3dDevice, "./shaders/mv_render.fx", NULL, NULL, NULL/*D3DXSHADER_PACKMATRIX_COLUMNMAJOR*/, NULL, &m_pEffect, NULL );
    // .fx file failed to compile
    if( FAILED( hr ) ) {
  		AfxMessageBox("ps_pass0.... -_-. Quitting...");
		return E_FAIL;
	}

	return S_OK;
	
}


//-----------------------------------------------------------------------------
// Name: CAppForm::RestoreDeviceObjects()
// Desc: Paired with InvalidateDeviceObjects()
//       The device exists, but may have just been Reset().  Resources in
//       D3DPOOL_DEFAULT and any other device state that persists during
//       rendering should be set here.  Render states, matrices, textures,
//       etc., that don't change during rendering can be set once here to
//       avoid redundant state setting during Render() or FrameMove().
//-----------------------------------------------------------------------------
HRESULT CAppForm::RestoreDeviceObjects()
{
    // TODO: setup render states

    //--------- Set up the sampler 0 (3D volume texture sampler)
    m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetSamplerState( 0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
	m_pd3dDevice->SetSamplerState( 0, D3DSAMP_BORDERCOLOR, 0x00000000);
	m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
	m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
	m_pd3dDevice->SetSamplerState( 0, D3DSAMP_ADDRESSW, D3DTADDRESS_BORDER);

	//---------- Set up the sampler 1 (3D gradient texture sampler)
    m_pd3dDevice->SetSamplerState( 1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetSamplerState( 1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
	m_pd3dDevice->SetSamplerState( 1, D3DSAMP_BORDERCOLOR, 0x00000000);
	m_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER );
	m_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER );
	m_pd3dDevice->SetSamplerState( 1, D3DSAMP_ADDRESSW, D3DTADDRESS_BORDER);

	//---------- Set up the sampler 2 (for 2D texture sampler) - PreInt Texture
    m_pd3dDevice->SetSamplerState( 2, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetSamplerState( 2, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
//	m_pd3dDevice->SetSamplerState( 2, D3DSAMP_MINFILTER, D3DTEXF_POINT );
//	m_pd3dDevice->SetSamplerState( 2, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
	//--- D3DTADDRESS_CLAMP 肺....  ------------
	m_pd3dDevice->SetSamplerState( 2, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
	m_pd3dDevice->SetSamplerState( 2, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );
//		m_pd3dDevice->SetSamplerState( 2, D3DSAMP_BORDERCOLOR, 0x00000000);
//	m_pd3dDevice->SetSamplerState( 2, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER );
//	m_pd3dDevice->SetSamplerState( 2, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER );

	//---------- Set up the sampler 3 (for 2D texture sampler) - InterTexture
	// shader 俊辑 texture offset ( + 1.0/ (512*2) ) 歹秦拎辑 point sampling 栏肺 秦拎具..
	//m_pd3dDevice->SetSamplerState( 3, D3DSAMP_MINFILTER, D3DTEXF_POINT );
    //m_pd3dDevice->SetSamplerState( 3, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
    m_pd3dDevice->SetSamplerState( 3, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetSamplerState( 3, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );   
	m_pd3dDevice->SetSamplerState( 3, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
	m_pd3dDevice->SetSamplerState( 3, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );

    //----------- Set up the sampler 4 (for 3D min-max texture)
   	m_pd3dDevice->SetSamplerState( 4, D3DSAMP_MINFILTER, D3DTEXF_POINT );
    m_pd3dDevice->SetSamplerState( 4, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
//	m_pd3dDevice->SetSamplerState( 4, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
//	m_pd3dDevice->SetSamplerState( 4, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR ); 
	m_pd3dDevice->SetSamplerState( 4, D3DSAMP_BORDERCOLOR, 0x00000000);
	m_pd3dDevice->SetSamplerState( 4, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER);
	m_pd3dDevice->SetSamplerState( 4, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER);
	m_pd3dDevice->SetSamplerState( 4, D3DSAMP_ADDRESSW, D3DTADDRESS_BORDER);

	//---------- Set up the sampler 5 - MPR Texture
    m_pd3dDevice->SetSamplerState( 5, D3DSAMP_MINFILTER, D3DTEXF_POINT );
    m_pd3dDevice->SetSamplerState( 5, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
	m_pd3dDevice->SetSamplerState( 5, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP );
	m_pd3dDevice->SetSamplerState( 5, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP );

	//---------- Set up the sampler 6 - MPR Mapper
    m_pd3dDevice->SetSamplerState( 6, D3DSAMP_MINFILTER, D3DTEXF_POINT );
    m_pd3dDevice->SetSamplerState( 6, D3DSAMP_MAGFILTER, D3DTEXF_POINT );
	m_pd3dDevice->SetSamplerState( 6, D3DSAMP_BORDERCOLOR, 0x00000000);
	m_pd3dDevice->SetSamplerState( 6, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER );
	m_pd3dDevice->SetSamplerState( 6, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER );
	
	//---------- Set up the sampler 7 - Virtual Volume
    m_pd3dDevice->SetSamplerState( 7, D3DSAMP_MINFILTER, D3DTEXF_LINEAR );
    m_pd3dDevice->SetSamplerState( 7, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR );
	m_pd3dDevice->SetSamplerState( 7, D3DSAMP_BORDERCOLOR, 0x00000000);
	m_pd3dDevice->SetSamplerState( 7, D3DSAMP_ADDRESSU, D3DTADDRESS_BORDER );
	m_pd3dDevice->SetSamplerState( 7, D3DSAMP_ADDRESSV, D3DTADDRESS_BORDER );

    // Set miscellaneous render states
    m_pd3dDevice->SetRenderState( D3DRS_DITHERENABLE,   FALSE );
    m_pd3dDevice->SetRenderState( D3DRS_SPECULARENABLE, FALSE );

	m_pd3dDevice->SetRenderState( D3DRS_CLIPPING, TRUE);
	m_pd3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_NONE);
	 
	m_pd3dDevice->SetRenderState( D3DRS_LIGHTING, FALSE);

	// RGBA blend
	m_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, TRUE);
	// Front to Back compositing
	m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_INVDESTALPHA);
	m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ONE);
/*	
	//test
	m_pd3dDevice->SetRenderState( D3DRS_SEPARATEALPHABLENDENABLE, TRUE);
	m_pd3dDevice->SetRenderState( D3DRS_SRCBLENDALPHA, D3DBLEND_INVDESTALPHA);
	m_pd3dDevice->SetRenderState( D3DRS_DESTBLENDALPHA, D3DBLEND_ONE);
*/	
	// Back to Front compositing
//	m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
//	m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
	// Opacity Weighted interpolation 捞骨肺 D3DBLEND_SRCALPHA 措脚 D3DBLEND_ONE !!
//	m_pd3dDevice->SetRenderState( D3DRS_SRCBLEND,     D3DBLEND_ONE);      
//	m_pd3dDevice->SetRenderState( D3DRS_DESTBLEND,    D3DBLEND_INVSRCALPHA );

	// enable clip planes
 	m_pd3dDevice->SetRenderState( D3DRS_CLIPPLANEENABLE, 
        D3DCLIPPLANE0 | D3DCLIPPLANE1 | D3DCLIPPLANE2 | D3DCLIPPLANE3 | D3DCLIPPLANE4 | D3DCLIPPLANE5);
  
    // Set the world matrix
   // D3DXMATRIX matIdentity;
   // D3DXMatrixIdentity( &matIdentity );
   // m_pd3dDevice->SetTransform( D3DTS_WORLD,  &matIdentity );

	// Set up our view matrix. A view matrix can be defined given an eye point,
    // a point to lookat, and a direction for which way is up. Here, we set the
    // eye five units back along the z-axis and up three units, look at the
    // origin, and define "up" to be in the y-direction.
    D3DXVECTOR3 vFromPt   = D3DXVECTOR3( 0.0f, 0.0f, -15.0f );
    D3DXVECTOR3 vLookatPt = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
    D3DXVECTOR3 vUpVec    = D3DXVECTOR3( 0.0f, 1.0f, 0.0f );
    D3DXMatrixLookAtLH( &matView, &vFromPt, &vLookatPt, &vUpVec );

	// set Orthogonal Projection.
	MSetOrthoProjection();



	////////////////// plane for MESH. /////////////////////////////

	// Restore the font
    m_pFont->RestoreDeviceObjects();

    return S_OK;
}

//-----------------------------------------------------------------------------
// Name: CAppForm::MSetOrthoProjection()
// Desc: Set Orthogonal Projection. 
//       Called in RestoreDeviceObjects(), OnMouseMove(UINT nFlags, CPoint point)
//-----------------------------------------------------------------------------
void CAppForm::MSetOrthoProjection()
{
	/*
	D3DVIEWPORT9 MainViewport;
	//m_pd3dDevice->GetViewport(&MainViewport);
	// Builds a left-handed orthogonal projection matrix
	MainViewport.Height = m_d3dpp.BackBufferHeight;
	MainViewport.Width = m_d3dpp.BackBufferWidth;

	if(MainViewport.Height == 0) MainViewport.Height = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -