Przeglądaj źródła

Viewer:
- additional fixed to make the viewer work without shaders. Still dummy, though, but now useful enough to allow me to work

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@175 67173fc5-114c-0410-ac8e-9d2fd5bffc1f

ulfjorensen 17 lat temu
rodzic
commit
f204ff0d45

+ 27 - 6
tools/assimp_view/Display.cpp

@@ -1671,6 +1671,10 @@ int CDisplay::HandleInputEmptyScene()
 //-------------------------------------------------------------------------------
 int CDisplay::DrawHUD()
 {
+  // HACK: (thom) can't get the effect to work on non-shader cards, therefore deactivated for the moment
+  if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
+    return 1;
+
 	// get the dimension of the back buffer
 	RECT sRect;
 	GetWindowRect(GetDlgItem(g_hDlg,IDC_RT),&sRect);
@@ -1688,7 +1692,10 @@ int CDisplay::DrawHUD()
 
 	// NOTE: The shader might be used for other purposes, too.
 	// So ensure the right technique is there
-	g_piPassThroughEffect->SetTechnique("PassThrough");
+  if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
+    g_piPassThroughEffect->SetTechnique( "PassThrough_FF");
+  else
+    g_piPassThroughEffect->SetTechnique("PassThrough");
 
 	// build vertices for drawing from system memory
 	UINT dw;
@@ -1877,9 +1884,11 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix,
 		apcVec[0].x = g_avLightDirs[0].x;
 		apcVec[0].y = g_avLightDirs[0].y;
 		apcVec[0].z = g_avLightDirs[0].z;
+    apcVec[0].w = 0.0f;
 		apcVec[1].x = g_avLightDirs[0].x * -1.0f;
 		apcVec[1].y = g_avLightDirs[0].y * -1.0f;
 		apcVec[1].z = g_avLightDirs[0].z * -1.0f;
+    apcVec[1].w = 0.0f;
 
 		D3DXVec4Normalize(&apcVec[0],&apcVec[0]);
 		D3DXVec4Normalize(&apcVec[1],&apcVec[1]);
@@ -1890,10 +1899,19 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix,
 		apcVec[0].z = ((g_avLightColors[0]) & 0xFF) / 255.0f;
 		apcVec[0].w = 1.0f;
 
-		apcVec[1].x = ((g_avLightColors[1] >> 16) & 0xFF) / 255.0f;
-		apcVec[1].y = ((g_avLightColors[1] >> 8) & 0xFF) / 255.0f;
-		apcVec[1].z = ((g_avLightColors[1]) & 0xFF) / 255.0f;
-		apcVec[1].w = 0.0f;
+    if( g_sOptions.b3Lights)
+    {
+		  apcVec[1].x = ((g_avLightColors[1] >> 16) & 0xFF) / 255.0f;
+		  apcVec[1].y = ((g_avLightColors[1] >> 8) & 0xFF) / 255.0f;
+		  apcVec[1].z = ((g_avLightColors[1]) & 0xFF) / 255.0f;
+		  apcVec[1].w = 0.0f;
+    } else
+    {
+		  apcVec[1].x = 0.0f;
+		  apcVec[1].y = 0.0f;
+		  apcVec[1].z = 0.0f;
+		  apcVec[1].w = 0.0f;
+    }
 
 		apcVec[0] *= g_fLightIntensity;
 		apcVec[1] *= g_fLightIntensity;
@@ -2143,7 +2161,10 @@ int CDisplay::RenderTextureView()
 	{
 		g_piPassThroughEffect->SetTechnique("PassThroughAlphaFromA");
 	}
-	else g_piPassThroughEffect->SetTechnique("PassThrough");
+	else if( g_sCaps.PixelShaderVersion < D3DPS_VERSION(2,0))
+    g_piPassThroughEffect->SetTechnique( "PassThrough_FF");
+  else
+    g_piPassThroughEffect->SetTechnique("PassThrough");
 
 	UINT dw;
 	g_piPassThroughEffect->Begin(&dw,0);

+ 15 - 4
tools/assimp_view/Material.cpp

@@ -1129,9 +1129,11 @@ int CMaterialManager::SetupMaterial (
 	apcVec[0].x = g_avLightDirs[0].x;
 	apcVec[0].y = g_avLightDirs[0].y;
 	apcVec[0].z = g_avLightDirs[0].z;
+  apcVec[0].w = 0.0f;
 	apcVec[1].x = g_avLightDirs[0].x * -1.0f;
 	apcVec[1].y = g_avLightDirs[0].y * -1.0f;
 	apcVec[1].z = g_avLightDirs[0].z * -1.0f;
+  apcVec[1].w = 0.0f;
 	D3DXVec4Normalize(&apcVec[0],&apcVec[0]);
 	D3DXVec4Normalize(&apcVec[1],&apcVec[1]);
 	piEnd->SetVectorArray("afLightDir",apcVec,5);
@@ -1141,10 +1143,19 @@ int CMaterialManager::SetupMaterial (
 	apcVec[0].z = ((g_avLightColors[0])			& 0xFF) / 255.0f;
 	apcVec[0].w = 1.0f;
 
-	apcVec[1].x = ((g_avLightColors[1] >> 16)	& 0xFF) / 255.0f;
-	apcVec[1].y = ((g_avLightColors[1] >> 8)	& 0xFF) / 255.0f;
-	apcVec[1].z = ((g_avLightColors[1])			& 0xFF) / 255.0f;
-	apcVec[1].w = 0.0f;
+  if( g_sOptions.b3Lights)
+  {
+	  apcVec[1].x = ((g_avLightColors[1] >> 16) & 0xFF) / 255.0f;
+	  apcVec[1].y = ((g_avLightColors[1] >> 8) & 0xFF) / 255.0f;
+	  apcVec[1].z = ((g_avLightColors[1]) & 0xFF) / 255.0f;
+	  apcVec[1].w = 0.0f;
+  } else
+  {
+	  apcVec[1].x = 0.0f;
+	  apcVec[1].y = 0.0f;
+	  apcVec[1].z = 0.0f;
+	  apcVec[1].w = 0.0f;
+  }
 
 	apcVec[0] *= g_fLightIntensity;
 	apcVec[1] *= g_fLightIntensity;

+ 6 - 6
tools/assimp_view/Shaders.cpp

@@ -302,11 +302,11 @@ std::string g_szDefaultShader = std::string(
 
 		// Multiply with the WorldViewProjection matrix
 		"Out.Position = mul(float4(IN.Position,1.0f),WorldViewProjection);\n"
-    "float3 worldNormal = mul( IN.Normal, (float3x3) WorldInverseTranspose); \n"
+    "float3 worldNormal = normalize( mul( IN.Normal, (float3x3) WorldInverseTranspose)); \n"
 
     // per-vertex lighting. We simply assume light colors of unused lights to be black
     "Out.Color = float4( 0.2f, 0.2f, 0.2f, 1.0f); \n"
-    "for( int a = 0; a < 5; a++)\n"
+    "for( int a = 0; a < 2; a++)\n"
     "  Out.Color.rgb += saturate( dot( afLightDir[a], worldNormal)) * afLightColor[a].rgb; \n"
 		"return Out;\n"
 	"}\n"
@@ -702,12 +702,12 @@ std::string g_szMaterialShader = std::string(
 		// Multiply with the WorldViewProjection matrix
 		"Out.Position = mul( float4( IN.Position, 1.0f), WorldViewProjection);\n"
 		"float3 worldPos = mul( float4( IN.Position, 1.0f), World);\n"
-    "float3 worldNormal = mul( IN.Normal, (float3x3) WorldInverseTranspose); \n"
+    "float3 worldNormal = normalize( mul( IN.Normal, (float3x3) WorldInverseTranspose)); \n"
 		"Out.TexCoord0 = IN.TexCoord0;\n"
 
     // calculate per-vertex diffuse lighting including ambient part
     "float4 diffuseColor = float4( 0.0f, 0.0f, 0.0f, 1.0f); \n"
-    "for( int a = 0; a < 5; a++) \n"
+    "for( int a = 0; a < 2; a++) \n"
     "  diffuseColor.rgb += saturate( dot( afLightDir[a], worldNormal)) * afLightColor[a].rgb; \n"
     // factor in material properties and a bit of ambient lighting
     "Out.DiffuseColor = diffuseColor * DIFFUSE_COLOR + float4( 0.2f, 0.2f, 0.2f, 1.0f) * AMBIENT_COLOR; ; \n"
@@ -716,10 +716,10 @@ std::string g_szMaterialShader = std::string(
     "float4 specularColor = float4( 0.0f, 0.0f, 0.0f, 1.0f); \n"
   	"#ifdef AV_SPECULAR_COMPONENT\n"
     "float3 viewDir = normalize( worldPos - vCameraPos); \n"
-    "for( int a = 0; a < 5; a++) \n"
+    "for( int a = 0; a < 2; a++) \n"
     "{ \n"
     "  float3 reflDir = reflect( afLightDir[a], worldNormal); \n"
-    "  float specIntensity = pow( dot( -reflDir, viewDir), SPECULAR_STRENGTH) * SPECULARITY; \n"
+    "  float specIntensity = pow( saturate( dot( reflDir, viewDir)), SPECULARITY) * SPECULAR_STRENGTH; \n"
     "  specularColor.rgb += afLightColor[a] * specIntensity; \n"
     "} \n"
     "#endif // AV_SPECULAR_COMPONENT\n"

+ 13 - 10
tools/assimp_view/assimp_view.cpp

@@ -910,17 +910,20 @@ int CreateDevice (bool p_bMultiSample,bool p_bSuperSample,bool bHW /*= true*/)
 		sParams.MultiSampleType = sMSOut;
 	}
 
-	// create the D3D9 device object
-	if(FAILED(g_piD3D->CreateDevice(0,eType,
-		g_hDlg,D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,&sParams,&g_piDevice)))
+  // preget the device capabilities. If the hardware vertex shader is too old, we prefer software vertex processing
+  g_piD3D->GetDeviceCaps( 0, D3DDEVTYPE_HAL, &g_sCaps);
+  DWORD creationFlags = D3DCREATE_MULTITHREADED;
+  if( g_sCaps.VertexShaderVersion >= D3DVS_VERSION( 2, 0))
+    creationFlags |= D3DCREATE_HARDWARE_VERTEXPROCESSING;
+  else
+    creationFlags |= D3DCREATE_SOFTWARE_VERTEXPROCESSING;
+
+	// create the D3D9 device object. with software-vertexprocessing if VS2.0 isn`t supported in hardware
+	if(FAILED(g_piD3D->CreateDevice(0,eType, g_hDlg, creationFlags ,&sParams,&g_piDevice)))
 	{
-		if(FAILED(g_piD3D->CreateDevice(0,eType,
-			g_hDlg,D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_MULTITHREADED,&sParams,&g_piDevice)))
-		{
-			// if hardware fails use software rendering instead
-			if (bHW)return CreateDevice(p_bMultiSample,p_bSuperSample,false);
-			return 0;
-		}
+		// if hardware fails use software rendering instead
+		if (bHW)return CreateDevice(p_bMultiSample,p_bSuperSample,false);
+		return 0;
 	}
 	g_piDevice->SetFVF(AssetHelper::Vertex::GetFVF());