• Advertisement
  • Popular Tags

  • Popular Now

  • Advertisement
  • Similar Content

    • By isu diss
      I'm following rastertek tutorial 14 (http://rastertek.com/tertut14.html). The problem is, slope based texturing doesn't work in my application. There are plenty of slopes in my terrain. None of them get slope color.
      float4 PSMAIN(DS_OUTPUT Input) : SV_Target { float4 grassColor; float4 slopeColor; float4 rockColor; float slope; float blendAmount; float4 textureColor; grassColor = txTerGrassy.Sample(SSTerrain, Input.TextureCoords); slopeColor = txTerMossRocky.Sample(SSTerrain, Input.TextureCoords); rockColor = txTerRocky.Sample(SSTerrain, Input.TextureCoords); // Calculate the slope of this point. slope = (1.0f - Input.LSNormal.y); if(slope < 0.2) { blendAmount = slope / 0.2f; textureColor = lerp(grassColor, slopeColor, blendAmount); } if((slope < 0.7) && (slope >= 0.2f)) { blendAmount = (slope - 0.2f) * (1.0f / (0.7f - 0.2f)); textureColor = lerp(slopeColor, rockColor, blendAmount); } if(slope >= 0.7) { textureColor = rockColor; } return float4(textureColor.rgb, 1); } Can anyone help me? Thanks.

    • By cozzie
      Hi all,
      As a part of the debug drawing system in my engine,  I want to add support for rendering simple text on screen  (aka HUD/ HUD style). From what I've read there are a few options, in short:
      1. Write your own font sprite renderer
      2. Using Direct2D/Directwrite, combine with DX11 rendertarget/ backbuffer
      3. Use an external library, like the directx toolkit etc.
      I want to go for number 2, but articles/ documentation confused me a bit. Some say you need to create a DX10 device, to be able to do this, because it doesn't directly work with the DX11 device.  But other articles tell that this was 'patched' later on and should work now.
      Can someone shed some light on this and ideally provide me an example or article on  how to set this up?
      All input is appreciated.
    • By stale
      I've just started learning about tessellation from Frank Luna's DX11 book. I'm getting some very weird behavior when I try to render a tessellated quad patch if I also render a mesh in the same frame. The tessellated quad patch renders just fine if it's the only thing I'm rendering. This is pictured below:
      However, when I attempt to render the same tessellated quad patch along with the other entities in the scene (which are simple triangle-lists), I get the following error:

      I have no idea why this is happening, and google searches have given me no leads at all. I use the following code to render the tessellated quad patch:
      ID3D11DeviceContext* dc = GetGFXDeviceContext(); dc->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_4_CONTROL_POINT_PATCHLIST); dc->IASetInputLayout(ShaderManager::GetInstance()->m_JQuadTess->m_InputLayout); float blendFactors[] = { 0.0f, 0.0f, 0.0f, 0.0f }; // only used with D3D11_BLEND_BLEND_FACTOR dc->RSSetState(m_rasterizerStates[RSWIREFRAME]); dc->OMSetBlendState(m_blendStates[BSNOBLEND], blendFactors, 0xffffffff); dc->OMSetDepthStencilState(m_depthStencilStates[DSDEFAULT], 0); ID3DX11EffectTechnique* activeTech = ShaderManager::GetInstance()->m_JQuadTess->Tech; D3DX11_TECHNIQUE_DESC techDesc; activeTech->GetDesc(&techDesc); for (unsigned int p = 0; p < techDesc.Passes; p++) { TerrainVisual* terrainVisual = (TerrainVisual*)entity->m_VisualComponent; UINT stride = sizeof(TerrainVertex); UINT offset = 0; GetGFXDeviceContext()->IASetVertexBuffers(0, 1, &terrainVisual->m_VB, &stride, &offset); Vector3 eyePos = Vector3(cam->m_position); Matrix rotation = Matrix::CreateFromYawPitchRoll(entity->m_rotationEuler.x, entity->m_rotationEuler.y, entity->m_rotationEuler.z); Matrix model = rotation * Matrix::CreateTranslation(entity->m_position); Matrix view = cam->GetLookAtMatrix(); Matrix MVP = model * view * m_ProjectionMatrix; ShaderManager::GetInstance()->m_JQuadTess->SetEyePosW(eyePos); ShaderManager::GetInstance()->m_JQuadTess->SetWorld(model); ShaderManager::GetInstance()->m_JQuadTess->SetWorldViewProj(MVP); activeTech->GetPassByIndex(p)->Apply(0, GetGFXDeviceContext()); GetGFXDeviceContext()->Draw(4, 0); } dc->RSSetState(0); dc->OMSetBlendState(0, blendFactors, 0xffffffff); dc->OMSetDepthStencilState(0, 0); I draw my scene by looping through the list of entities and calling the associated draw method depending on the entity's "visual type":
      for (unsigned int i = 0; i < scene->GetEntityList()->size(); i++) { Entity* entity = scene->GetEntityList()->at(i); if (entity->m_VisualComponent->m_visualType == VisualType::MESH) DrawMeshEntity(entity, cam, sun, point); else if (entity->m_VisualComponent->m_visualType == VisualType::BILLBOARD) DrawBillboardEntity(entity, cam, sun, point); else if (entity->m_VisualComponent->m_visualType == VisualType::TERRAIN) DrawTerrainEntity(entity, cam); } HR(m_swapChain->Present(0, 0)); Any help/advice would be much appreciated!
    • By KaiserJohan
      Am trying a basebones tessellation shader and getting unexpected result when increasing the tessellation factor. Am rendering a group of quads and trying to apply tessellation to them.
      OutsideTess = (1,1,1,1), InsideTess= (1,1)

      OutsideTess = (1,1,1,1), InsideTess= (2,1)

      I expected 4 triangles in the quad, not two. Any idea of whats wrong?
      struct PatchTess { float mEdgeTess[4] : SV_TessFactor; float mInsideTess[2] : SV_InsideTessFactor; }; struct VertexOut { float4 mWorldPosition : POSITION; float mTessFactor : TESS; }; struct DomainOut { float4 mWorldPosition : SV_POSITION; }; struct HullOut { float4 mWorldPosition : POSITION; }; Hull shader:
      PatchTess PatchHS(InputPatch<VertexOut, 3> inputVertices) { PatchTess patch; patch.mEdgeTess[ 0 ] = 1; patch.mEdgeTess[ 1 ] = 1; patch.mEdgeTess[ 2 ] = 1; patch.mEdgeTess[ 3 ] = 1; patch.mInsideTess[ 0 ] = 2; patch.mInsideTess[ 1 ] = 1; return patch; } [domain("quad")] [partitioning("fractional_odd")] [outputtopology("triangle_ccw")] [outputcontrolpoints(4)] [patchconstantfunc("PatchHS")] [maxtessfactor( 64.0 )] HullOut hull_main(InputPatch<VertexOut, 3> verticeData, uint index : SV_OutputControlPointID) { HullOut ret; ret.mWorldPosition = verticeData[index].mWorldPosition; return ret; }  
      Domain shader:
      [domain("quad")] DomainOut domain_main(PatchTess patchTess, float2 uv : SV_DomainLocation, const OutputPatch<HullOut, 4> quad) { DomainOut ret; const float MipInterval = 20.0f; ret.mWorldPosition.xz = quad[ 0 ].mWorldPosition.xz * ( 1.0f - uv.x ) * ( 1.0f - uv.y ) + quad[ 1 ].mWorldPosition.xz * uv.x * ( 1.0f - uv.y ) + quad[ 2 ].mWorldPosition.xz * ( 1.0f - uv.x ) * uv.y + quad[ 3 ].mWorldPosition.xz * uv.x * uv.y ; ret.mWorldPosition.y = quad[ 0 ].mWorldPosition.y; ret.mWorldPosition.w = 1; ret.mWorldPosition = mul( gFrameViewProj, ret.mWorldPosition ); return ret; }  
      Any ideas what could be wrong with these shaders?
    • By simco50
      I've stumbled upon Urho3D engine and found that it has a really nice and easy to read code structure.
      I think the graphics abstraction looks really interesting and I like the idea of how it defers pipeline state changes until just before the draw call to resolve redundant state changes.
      This is done by saving the state changes (blendEnabled/SRV changes/RTV changes) in member variables and just before the draw, apply the actual state changes using the graphics context.
      It looks something like this (pseudo):
      void PrepareDraw() { if(renderTargetsDirty) { pD3D11DeviceContext->OMSetRenderTarget(mCurrentRenderTargets); renderTargetsDirty = false } if(texturesDirty) { pD3D11DeviceContext->PSSetShaderResourceView(..., mCurrentSRVs); texturesDirty = false } .... //Some more state changes } This all looked like a great design at first but I've found that there is one big issue with this which I don't really understand how it is solved in their case and how I would tackle it.
      I'll explain it by example, imagine I have two rendertargets: my backbuffer RT and an offscreen RT.
      Say I want to render my backbuffer to the offscreen RT and then back to the backbuffer (Just for the sake of the example).
      You would do something like this:
      //Render to the offscreen RT pGraphics->SetRenderTarget(pOffscreenRT->GetRTV()); pGraphics->SetTexture(diffuseSlot, pDefaultRT->GetSRV()) pGraphics->DrawQuad() pGraphics->SetTexture(diffuseSlot, nullptr); //Remove the default RT from input //Render to the default (screen) RT pGraphics->SetRenderTarget(nullptr); //Default RT pGraphics->SetTexture(diffuseSlot, pOffscreenRT->GetSRV()) pGraphics->DrawQuad(); The problem here is that the second time the application loop comes around, the offscreen rendertarget is still bound as input ShaderResourceView when it gets set as a RenderTargetView because in Urho3D, the state of the RenderTargetView will always be changed before the ShaderResourceViews (see top code snippet) even when I set the SRV to nullptr before using it as a RTV like above causing errors because a resource can't be bound to both input and rendertarget.
      What is usually the solution to this?
  • Advertisement
  • Advertisement

DX11 Loading FBX with Directx 11

Recommended Posts

HRESULT FBXLoader::Open(HWND hWnd, char* Filename)
	if (FBXM)
		FBXIOS = FbxIOSettings::Create(FBXM, IOSROOT);

		FBXI = FbxImporter::Create(FBXM, "");

		if (!(FBXI->Initialize(Filename, -1, FBXIOS)))
			MessageBox(hWnd, (wchar_t*)FBXI->GetStatus().GetErrorString(), TEXT("ALM"), MB_OK);

		FBXS = FbxScene::Create(FBXM, "MCS"); 
		if (!FBXS)
			MessageBox(hWnd, TEXT("Failed to create the scene"), TEXT("ALM"), MB_OK);

		if (!(FBXI->Import(FBXS)))
			MessageBox(hWnd, TEXT("Failed to import fbx file content into the scene"), TEXT("ALM"), MB_OK);

		if (FBXI)

		FbxNode*	MainNode = FBXS->GetRootNode();
		int			NumKids = MainNode->GetChildCount();
		FbxNode*	ChildNode = NULL;

		for (int i=0; i<NumKids; i++)
			ChildNode = MainNode->GetChild(i);
			FbxNodeAttribute* NodeAttribute = ChildNode->GetNodeAttribute();
			if (NodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
				FbxMesh* Mesh = ChildNode->GetMesh();

				NumVertices = Mesh->GetControlPointsCount();//number of vertices
				MyV = new FBXVTX[NumVertices];

				for (DWORD j = 0; j < NumVertices; j++)
					FbxVector4 Vertex = Mesh->GetControlPointAt(j);//Gets the control point at the specified index. 
					MyV[j].Position = XMFLOAT3((float)Vertex.mData[0], (float)Vertex.mData[1], (float)Vertex.mData[2]);


				NumIndices = Mesh->GetPolygonVertexCount();//number of indices; for cube 20
				MyI = new DWORD[NumIndices];
				MyI = (DWORD*)Mesh->GetPolygonVertices();//index array

				NumFaces = Mesh->GetPolygonCount();
				MyF = new FBXFACEX[NumFaces];
				for (int l=0;l<NumFaces;l++)
					MyF[l].Vertices[0] = MyI[4*l];
					MyF[l].Vertices[1] = MyI[4*l+1];
					MyF[l].Vertices[2] = MyI[4*l+2];
					MyF[l].Vertices[3] = MyI[4*l+3];

				UV = new XMFLOAT2[NumIndices];
				for (int i = 0; i < Mesh->GetPolygonCount(); i++)//polygon(=mostly rectangle) count
				  FbxLayerElementArrayTemplate<FbxVector2>* uvVertices = NULL;

				  for (int j = 0; j < Mesh->GetPolygonSize(i); j++)//retrieves number of vertices in a polygon
					 FbxVector2 uv = uvVertices->GetAt(Mesh->GetTextureUVIndex(i, j));
					 UV[4*i+j] = XMFLOAT2((float)uv.mData[0], (float)uv.mData[1]);
		MessageBox(hWnd, TEXT("Failed to create the FBX Manager"), TEXT("ALM"), MB_OK);

	return hr;

I've been trying to load fbx files(cube.fbx) into my programme. but I get this. Can someone pls help me?



Share this post

Link to post
Share on other sites
MyI = new DWORD[NumIndices];
MyI = (DWORD*)Mesh->GetPolygonVertices();//index array

Unrelated: the first line shouldn't be there, you're allocating an array and forgetting about it right after!

Share this post

Link to post
Share on other sites
				//Loop through the polygons
				for (int p = 0; p < Mesh->GetPolygonCount(); p++)
					//Loop through the three vertices within each polygon
					for(int v = 0; v < Mesh->GetPolygonSize(p); v++)
						 FbxStringList UVSetNameList;
						 Mesh->GetUVSetNames( UVSetNameList );

						FbxVector2 tex;
						bool isMapped;
						Mesh->GetPolygonVertexUV(p, v, UVSetNameList.GetStringAt(0), tex, isMapped);
						MyV[3*p+v].TexCoords = XMFLOAT2((float)tex.mData[0], (float)tex.mData[1]);


I'm having a problem loading UV coordinates from FBX. Is above code correct? what should I do?


Share this post

Link to post
Share on other sites

Now I understand the problem but I don't know how to fix it. FBX stores UVs as per index. What I should do is load UV indices into Direct3D which I don't know. This should work if it's per vertex.

Vertices = new VTX[MyFBX->NumVertices];
for(DWORD i=0;i<MyFBX->NumVertices;i++)
	Vertices[i].Position = MyFBX->MyV[i];
	Vertices[i].TextureCoords = MyFBX->MyUV[i];

I understood that by loading simple plane.fbx. here are the screen shots.





Share this post

Link to post
Share on other sites

The problem is not only with texcoords but with any additional properties past the position.

If you take the example of a cube, you have 8 corner positions, 6 possible normals ( one per face ) and 4 texture coordinates possible if we consider a full wrap per face.

It means that a full vertex index is in fact a tuple of 3 index (pos idx, uv idx , normal idx). This is the kind of representation you can find in an OBJ file for example or in a FBX.

Because D3D only support a single index to fetch the complete vertex. It means you need to duplicate position/uv/normals into new vertices when appropriate. And to do so is easy, just create a dictionary like this std::map<std::tuple<int,int,int>,int> dico; and have an int nextVertexIdx. The key is your triplet, every time a triplet is not yet in the map, just insert it and allocate a vertex:  dico[triplet] = nextVertexIdx++;

Once you proceed with all the FBX indices and you have all the existing triplet, nextVertexIdx contains the number of vertices you need in your final vertex buffer. The dictionary also let you know what position/uv/normals to copy for each vertex ( if you invert it by swapping key/value in a second std::map ), And of course, generate the index buffer by looking from triplet to vertex index.


Share this post

Link to post
Share on other sites

I can load all the position values and indices correctly. And I can render the model correctly via D3D DrawIndexed call. The only problem is loading UVs. I got your idea but my c++ knowledge is not so good. Can you give me a source code snippet?

Share this post

Link to post
Share on other sites
10 hours ago, isu diss said:

I can load all the position values and indices correctly. And I can render the model correctly via D3D DrawIndexed call. The only problem is loading UVs. I got your idea but my c++ knowledge is not so good. Can you give me a source code snippet?

No, we are here to help, not to do the work for you. Or you would never learn, especially with something that basic.


Reread my answer, look at loading obj file tutorial, try and come ask help with your code if blocked.

Edited by galop1n

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement