Files
UnrealEngineUWP/Engine/Source/Programs/UnrealLightmass/Private/ImportExport/3DVisualizer.cpp

395 lines
13 KiB
C++
Raw Normal View History

// Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340) #lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3209340 on 2016/11/23 by Ben.Marsh Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h. Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms. * Every header now includes everything it needs to compile. * There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first. * There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h. * Every .cpp file includes its matching .h file first. * This helps validate that each header is including everything it needs to compile. * No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more. * You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there. * There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible. * No engine code explicitly includes a precompiled header any more. * We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies. * PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files. Tool used to generate this transform is at Engine\Source\Programs\IncludeTool. [CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
#include "3DVisualizer.h"
#if PLATFORM_WINDOWS
Copying //UE4/Dev-Build to //UE4/Dev-Main (Source: //UE4/Dev-Build @ 3209340) #lockdown Nick.Penwarden #rb none ========================== MAJOR FEATURES + CHANGES ========================== Change 3209340 on 2016/11/23 by Ben.Marsh Convert UE4 codebase to an "include what you use" model - where every header just includes the dependencies it needs, rather than every source file including large monolithic headers like Engine.h and UnrealEd.h. Measured full rebuild times around 2x faster using XGE on Windows, and improvements of 25% or more for incremental builds and full rebuilds on most other platforms. * Every header now includes everything it needs to compile. * There's a CoreMinimal.h header that gets you a set of ubiquitous types from Core (eg. FString, FName, TArray, FVector, etc...). Most headers now include this first. * There's a CoreTypes.h header that sets up primitive UE4 types and build macros (int32, PLATFORM_WIN64, etc...). All headers in Core include this first, as does CoreMinimal.h. * Every .cpp file includes its matching .h file first. * This helps validate that each header is including everything it needs to compile. * No engine code includes a monolithic header such as Engine.h or UnrealEd.h any more. * You will get a warning if you try to include one of these from the engine. They still exist for compatibility with game projects and do not produce warnings when included there. * There have only been minor changes to our internal games down to accommodate these changes. The intent is for this to be as seamless as possible. * No engine code explicitly includes a precompiled header any more. * We still use PCHs, but they're force-included on the compiler command line by UnrealBuildTool instead. This lets us tune what they contain without breaking any existing include dependencies. * PCHs are generated by a tool to get a statistical amount of coverage for the source files using it, and I've seeded the new shared PCHs to contain any header included by > 15% of source files. Tool used to generate this transform is at Engine\Source\Programs\IncludeTool. [CL 3209342 by Ben Marsh in Main branch]
2016-11-23 15:48:37 -05:00
#include "WindowsHWrapper.h"
#include "AllowWindowsPlatformTypes.h"
#include <d3dx9.h>
#include "HideWindowsPlatformTypes.h"
namespace Lightmass
{
/**
* Helper wrapper to encapsulate D3D-specific variables.
*/
struct FD3DWrapper
{
/** Constructor */
FD3DWrapper()
: D3D(NULL)
, D3DDevice(NULL)
{
}
/** DirectX 9.0 interface */
IDirect3D9* D3D;
/** DirectX 9.0 device */
IDirect3DDevice9* D3DDevice;
};
/**
* D3D FVF vertex, stored in the .x file.
*/
struct D3DXVertex
{
/** Vertex positionm, world space. */
float Pos[3];
/** Unit normal. */
float Normal[3];
/** Diffuse vertex color. */
D3DCOLOR Color1;
/** Emissive vertex color. */
D3DCOLOR Color2;
};
extern const char* ShaderFxFile;
/** Constructor. Initializes a D3D Device. */
F3DVisualizer::F3DVisualizer()
{
D3D = new FD3DWrapper;
HRESULT Result;
D3D->D3D = Direct3DCreate9(D3D_SDK_VERSION);
D3D->D3DDevice = NULL;
D3DPRESENT_PARAMETERS D3Dpp;
ZeroMemory( &D3Dpp, sizeof(D3Dpp) );
D3Dpp.Windowed = true;
D3Dpp.SwapEffect = D3DSWAPEFFECT_COPY;
Result = D3D->D3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetDesktopWindow(), D3DCREATE_HARDWARE_VERTEXPROCESSING|D3DCREATE_NOWINDOWCHANGES, &D3Dpp, &D3D->D3DDevice );
}
/** Destructor. Destroys the D3D Device. */
F3DVisualizer::~F3DVisualizer()
{
D3D->D3DDevice->Release();
D3D->D3D->Release();
delete D3D;
}
/** Returns the current number of triangles. */
int32 F3DVisualizer::NumTriangles() const
{
return Triangles.Num();
}
/** Returns the current number of lines. */
int32 F3DVisualizer::NumLines() const
{
return Lines.Num();
}
/** Removes all geometry. */
void F3DVisualizer::Clear()
{
Triangles.Empty();
Lines.Empty();
}
/**
* Adds a triangle to be visualized.
* @param P1 First vertex of the triangle
* @param P2 Second vertex of the triangle
* @param P3 Third vertex of the triangle
* @param Color Color of the triangle
*/
void F3DVisualizer::AddTriangle( const FVector4& P1, const FVector4& P2, const FVector4& P3, FColor Color )
{
Triangles.Add( FTriangle(P1, P2, P3, Color) );
}
/**
* Adds a triangle to be visualized.
* @param P1 First vertex of the line
* @param P2 Second vertex of the line
* @param Color Color of the line
*/
void F3DVisualizer::AddLine( const FVector4& P1, const FVector4& P2, FColor Color )
{
Lines.Add( FLine(P1, P2, Color) );
}
/**
* Exports all geometry into a D3D .x file into the current working folder.
* @param Filename Desired filename (may include path)
* @param bShow Whether the D3D .x file viewer should be invoked. If shown, we'll block until it has been closed.
*/
void F3DVisualizer::Export( const TCHAR* Filename, bool bShow/*=false*/ )
{
ID3DXMesh* Mesh;
Mesh = NULL;
int32 NumPrimitives = NumTriangles() + NumLines()*2;
int32 NumVertices = NumTriangles()*3 + NumLines()*4;
HRESULT Result = D3DXCreateMeshFVF( NumPrimitives, NumVertices, D3DXMESH_32BIT, D3DFVF_XYZ|D3DFVF_NORMAL|D3DFVF_DIFFUSE|D3DFVF_SPECULAR, D3D->D3DDevice, &Mesh );
void* VertexBuffer = NULL;
void* IndexBuffer = NULL;
Result = Mesh->LockVertexBuffer(D3DLOCK_DISCARD, &VertexBuffer);
Result = Mesh->LockIndexBuffer(D3DLOCK_DISCARD, &IndexBuffer);
D3DXVertex* Vertices = (D3DXVertex*)VertexBuffer;
uint32* Indices = (uint32*) IndexBuffer;
int32 NumVerticesStored = 0;
int32 NumIndicesStored = 0;
// Add the triangles to the vertexbuffer and indexbuffer.
for ( int32 TriangleIndex=0; TriangleIndex < NumTriangles(); ++TriangleIndex )
{
const FVector4& P1 = Triangles[TriangleIndex].Vertices[0];
const FVector4& P2 = Triangles[TriangleIndex].Vertices[1];
const FVector4& P3 = Triangles[TriangleIndex].Vertices[2];
const FColor& Color = Triangles[TriangleIndex].Color;
Vertices[NumVerticesStored+0].Pos[0] = P1[0];
Vertices[NumVerticesStored+0].Pos[1] = P1[1];
Vertices[NumVerticesStored+0].Pos[2] = P1[2];
Vertices[NumVerticesStored+0].Color1 = Color.DWColor();
Vertices[NumVerticesStored+0].Color2 = 0;
Vertices[NumVerticesStored+1].Pos[0] = P2[0];
Vertices[NumVerticesStored+1].Pos[1] = P2[1];
Vertices[NumVerticesStored+1].Pos[2] = P2[2];
Vertices[NumVerticesStored+1].Color1 = Color.DWColor();
Vertices[NumVerticesStored+1].Color2 = 0;
Vertices[NumVerticesStored+2].Pos[0] = P3[0];
Vertices[NumVerticesStored+2].Pos[1] = P3[1];
Vertices[NumVerticesStored+2].Pos[2] = P3[2];
Vertices[NumVerticesStored+2].Color1 = Color.DWColor();
Vertices[NumVerticesStored+2].Color2 = 0;
// Reverse triangle winding order for the .x file.
Indices[NumIndicesStored+0] = NumVerticesStored + 0;
Indices[NumIndicesStored+1] = NumVerticesStored + 2;
Indices[NumIndicesStored+2] = NumVerticesStored + 1;
NumVerticesStored += 3;
NumIndicesStored += 3;
}
// Add the lines to the vertexbuffer and indexbuffer.
for ( int32 LineIndex=0; LineIndex < NumLines(); ++LineIndex )
{
const FVector4& P1 = Lines[LineIndex].Vertices[0];
const FVector4& P2 = Lines[LineIndex].Vertices[1];
const FColor& Color = Lines[LineIndex].Color;
Vertices[NumVerticesStored+0].Pos[0] = P1[0];
Vertices[NumVerticesStored+0].Pos[1] = P1[1] - 5.0f;
Vertices[NumVerticesStored+0].Pos[2] = P1[2];
Vertices[NumVerticesStored+0].Color1 = 0;
Vertices[NumVerticesStored+0].Color2 = Color.DWColor();
Vertices[NumVerticesStored+1].Pos[0] = P1[0];
Vertices[NumVerticesStored+1].Pos[1] = P1[1] + 5.0f;
Vertices[NumVerticesStored+1].Pos[2] = P1[2];
Vertices[NumVerticesStored+1].Color1 = 0;
Vertices[NumVerticesStored+1].Color2 = Color.DWColor();
Vertices[NumVerticesStored+2].Pos[0] = P2[0];
Vertices[NumVerticesStored+2].Pos[1] = P2[1] - 5.0f;
Vertices[NumVerticesStored+2].Pos[2] = P2[2];
Vertices[NumVerticesStored+2].Color1 = 0;
Vertices[NumVerticesStored+2].Color2 = Color.DWColor();
Vertices[NumVerticesStored+3].Pos[0] = P2[0];
Vertices[NumVerticesStored+3].Pos[1] = P2[1] + 5.0f;
Vertices[NumVerticesStored+3].Pos[2] = P2[2];
Vertices[NumVerticesStored+3].Color1 = 0;
Vertices[NumVerticesStored+3].Color2 = Color.DWColor();
Indices[NumIndicesStored+0] = NumVerticesStored+0;
Indices[NumIndicesStored+1] = NumVerticesStored+2;
Indices[NumIndicesStored+2] = NumVerticesStored+1;
Indices[NumIndicesStored+3] = NumVerticesStored+2;
Indices[NumIndicesStored+4] = NumVerticesStored+3;
Indices[NumIndicesStored+5] = NumVerticesStored+1;
NumVerticesStored += 4;
NumIndicesStored += 6;
}
Mesh->UnlockVertexBuffer();
Mesh->UnlockIndexBuffer();
Result = D3DXComputeNormals( Mesh, NULL );
D3DXMATERIAL MeshMaterial;
MeshMaterial.MatD3D.Ambient.r = 0.1f;
MeshMaterial.MatD3D.Ambient.g = 0.1f;
MeshMaterial.MatD3D.Ambient.b = 0.1f;
MeshMaterial.MatD3D.Ambient.a = 0.0f;
MeshMaterial.MatD3D.Diffuse.r = 1.0f;
MeshMaterial.MatD3D.Diffuse.g = 1.0f;
MeshMaterial.MatD3D.Diffuse.b = 1.0f;
MeshMaterial.MatD3D.Diffuse.a = 1.0f;
MeshMaterial.MatD3D.Emissive.r = 1.0f;
MeshMaterial.MatD3D.Emissive.g = 1.0f;
MeshMaterial.MatD3D.Emissive.b = 1.0f;
MeshMaterial.MatD3D.Emissive.a = 1.0f;
MeshMaterial.MatD3D.Specular.r = 1.0f;
MeshMaterial.MatD3D.Specular.g = 1.0f;
MeshMaterial.MatD3D.Specular.b = 1.0f;
MeshMaterial.MatD3D.Specular.a = 1.0f;
MeshMaterial.MatD3D.Power = 16.0f;
MeshMaterial.pTextureFilename = NULL;
D3DXEFFECTINSTANCE EffectInstance;
EffectInstance.pEffectFilename = "D3DExport.fx";
EffectInstance.NumDefaults = 0;
EffectInstance.pDefaults = NULL;
// Write out the .x file.
D3DXSaveMeshToX( Filename, Mesh, NULL, &MeshMaterial, &EffectInstance, 1, D3DXF_FILEFORMAT_BINARY );
Mesh->Release();
// Write out the .fx file, if it doesn't always exist.
HANDLE ShaderFile = CreateFile( TEXT("D3DExport.fx"), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (ShaderFile != INVALID_HANDLE_VALUE)
{
::DWORD BytesWritten;
WriteFile(ShaderFile, ShaderFxFile, (uint32)FCStringAnsi::Strlen(ShaderFxFile), &BytesWritten, NULL);
CloseHandle( ShaderFile );
}
// If specified, run the default viewer for .x files and block until it's closed.
if ( bShow )
{
system( TCHAR_TO_ANSI(Filename) );
}
}
const char* ShaderFxFile =
"int sas : SasGlobal\n"
"<\n"
" bool SasUiVisible = false;\n"
" int3 SasVersion= {1,1,0};\n"
">;\n"
"\n"
"float4x4 g_mWorld : WORLD\n"
"<\n"
" bool SasUiVisible = false;\n"
" string SasBindAddress= \"Sas.Skeleton.MeshToJointToWorld[0]\";\n"
">; \n"
"\n"
"float4x4 g_mView : VIEW\n"
"<\n"
" bool SasUiVisible = false;\n"
" string SasBindAddress= \"Sas.Camera.WorldToView\";\n"
">; \n"
"\n"
"float4x4 g_mProj : PROJECTION\n"
"<\n"
" bool SasUiVisible = false;\n"
" string SasBindAddress= \"Sas.Camera.Projection\";\n"
">;\n"
"\n"
"float4 g_vLightColor\n"
"<\n"
" bool SasUiVisible = false;\n"
" string SasBindAddress= \"Sas.PointLight[0].Color\";\n"
"> = {1.0f, 1.0f, 1.0f, 1.0f}; // Light value\n"
"\n"
"float3 g_vLight\n"
"< \n"
" bool SasUiVisible = false;\n"
" string SasBindAddress= \"Sas.PointLight[0].Position\";\n"
"> = {0.0f, 3.0f, -100.0f};\n"
"\n"
"// Object material attributes\n"
"float4 Diffuse\n"
"<\n"
" string SasUiControl = \"ColorPicker\";\n"
"> = { 0.5f, 0.5f, 0.5, 1.0f}; // Diffuse color of the material\n"
"\n"
"float4 Specular\n"
"<\n"
" string SasUiControl = \"ColorPicker\";\n"
"> = {1.0f, 1.0f, 1.0f, 1.0f}; // Specular color of the material\n"
"\n"
"float Power\n"
"<\n"
" string SasUiLabel = \"Specular Power\";\n"
" string SasUiControl = \"Slider\"; \n"
" float SasUiMin = 1.0f; \n"
" float SasUiMax = 32.0f; \n"
" int SasUiSteps = 31;\n"
"\n"
"> = 8.0f;\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"// Vertex shader output structure\n"
"//--------------------------------------------------------------------------------------\n"
"struct VS_OUTPUT\n"
"{\n"
" float4 Position : POSITION; // vertex position \n"
" float4 Diffuse : COLOR0; // vertex diffuse color (note that COLOR0 is clamped from 0..1)\n"
"// float2 TextureUV : TEXCOORD0; // vertex texture coords \n"
"};\n"
"\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"// This shader computes standard transform and lighting\n"
"//--------------------------------------------------------------------------------------\n"
"VS_OUTPUT RenderSceneVS( float4 vPos : POSITION, \n"
" float3 vNormal : NORMAL,\n"
" float4 vColor1 : COLOR0,\n"
" float4 vColor2 : COLOR1 )\n"
"// float2 vTexCoord0 : TEXCOORD0 )\n"
"{\n"
" VS_OUTPUT Output;\n"
" \n"
" float4x4 g_mWorldView= mul(g_mWorld, g_mView);\n"
" float4x4 g_mWorldViewProjection= mul(g_mWorldView, g_mProj);\n"
" float4 lightInView= mul( g_vLight, g_mView);\n"
"\n"
" // Transform the position from object space to homogeneous projection space\n"
" Output.Position = mul( vPos, g_mWorldViewProjection );\n"
"\n"
" // Compute the view-space position\n"
" float4 ViewPos = mul( vPos, g_mWorldView );\n"
"\n"
" // Compute view-space normal\n"
" float3 ViewNormal = normalize( mul( vNormal, (float3x3)g_mWorldView ) );\n"
"\n"
" // Compute diffuse lighting\n"
" Output.Diffuse = dot( ViewNormal, normalize( lightInView - ViewPos ) ) * Diffuse * vColor1 + vColor2;\n"
" \n"
" return Output; \n"
"}\n"
"\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"// Pixel shader output structure\n"
"//--------------------------------------------------------------------------------------\n"
"struct PS_OUTPUT\n"
"{\n"
" float4 RGBColor : COLOR0; // Pixel color \n"
"};\n"
"\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"// This shader outputs the pixel's color by modulating the texture's\n"
"// color with diffuse material color\n"
"//--------------------------------------------------------------------------------------\n"
"PS_OUTPUT RenderScenePS( VS_OUTPUT In ) \n"
"{ \n"
" PS_OUTPUT Output;\n"
"\n"
" // Lookup mesh texture and modulate it with diffuse\n"
" // Output.RGBColor = tex2D(MeshTextureSampler, In.TextureUV) * In.Diffuse;\n"
" Output.RGBColor = In.Diffuse;\n"
"\n"
" return Output;\n"
"}\n"
"\n"
"\n"
"//--------------------------------------------------------------------------------------\n"
"// Renders scene \n"
"//--------------------------------------------------------------------------------------\n"
"technique RenderScene\n"
"{\n"
" pass P0\n"
" { \n"
" VertexShader = compile vs_2_0 RenderSceneVS();\n"
" PixelShader = compile ps_2_0 RenderScenePS(); \n"
" CullMode = None;\n"
" }\n"
"}\n";
}
#endif // PLATFORM_WINDOWS