Xedi.Xermawan's Blog

personal-technical blog

Posts Tagged ‘utah teapot

[3] on directx 11 : load 3D model from file

leave a comment »

di project sebelumnya saya hanya menggambar 3d kubus. sangat menarik jika program bisa me-load model 3D yang dibuat oleh 3D editor. format paling populer untuk coba-coba tentu adalah wavefront obj 🙂 . File .obj ini hanya bisa untuk static 3d model, tidak mendukung animasi. Dan biasanya ada 1 file pasangan tambahan untuk setiap .obj yaitu .mtl.  File .mtl dimaksudkan untuk menyimpan material ( konstanta pencahayaan , seperti diffuse, spekular ) . namun .mtl file ini optional. File .obj sebenarnya adalah text file. terdapat 2 kata disini “3D model” & “text file”, dan pasti yang terbayang adalah parsing yang lamaaaa . dan memang iya. parsingnya lama. untuk mengakali ini , .obj diubah ke .vbo ( ada orang yang sudah buat tool converter .obj to .vbo . .vbo apa itu?, .vbo sebenarnya adalah versi binary dari .obj, sehingga tidak perlu ada proses parsing waktu load object. 1 fungsi tambahan LoadModel_VBO, dan saya mengubah informasi vertex menjadi :
DirectX::XMFLOAT3 position;
DirectX::XMFLOAT3 normal;
DirectX::XMFLOAT2 texcoord;

fungsi load VBO :

	void LoadModel_VBO( unsigned char* meshData, ID3D11Buffer** vertexBuffer,ID3D11Buffer** indexBuffer,int& vertexCount,int& indexCount)  {
		// The first 4 bytes of the BasicMesh format define the number of vertices in the mesh.
		int numVertices = *reinterpret_cast<int*>(meshData);

		// The following 4 bytes define the number of indices in the mesh.
		int numIndices = *reinterpret_cast<int*>(meshData + sizeof(int));

		// The next segment of the BasicMesh format contains the vertices of the mesh.
		vertex_type* vertices = reinterpret_cast<vertex_type*>(meshData + sizeof(int) * 2);

		// The last segment of the BasicMesh format contains the indices of the mesh.
		unsigned short* indices = reinterpret_cast<unsigned short*>(meshData + sizeof(int) * 2 + sizeof(vertex_type) * numVertices);

		// Create the vertex and index buffers with the mesh data.

		D3D11_SUBRESOURCE_DATA vertexBufferData = {0};
		vertexBufferData.pSysMem = vertices;
		vertexBufferData.SysMemPitch = 0;
		vertexBufferData.SysMemSlicePitch = 0;
		CD3D11_BUFFER_DESC vertexBufferDesc(numVertices * sizeof(vertex_type), D3D11_BIND_VERTEX_BUFFER);
		HRESULT hr = m_Device->CreateBuffer(
				&vertexBufferDesc,
				&vertexBufferData,
				vertexBuffer
				);
		assert( hr==S_OK );

		D3D11_SUBRESOURCE_DATA indexBufferData = {0};
		indexBufferData.pSysMem = indices;
		indexBufferData.SysMemPitch = 0;
		indexBufferData.SysMemSlicePitch = 0;
		CD3D11_BUFFER_DESC indexBufferDesc(numIndices * sizeof(unsigned short), D3D11_BIND_INDEX_BUFFER);
			m_Device->CreateBuffer(
				&indexBufferDesc,
				&indexBufferData,
				indexBuffer
				);
		assert( hr==S_OK );
		vertexCount = numVertices;
		indexCount = numIndices;
	}

output program ( saya me-load utah teapot –yang terkenal itu  ) :

teapot

full source code & project ( vs 2012 desktop ) . ( xedi_on_directx11___3___from___N.vcxproj )

svn checkout : https://xedi-on-directx-11.googlecode.com/svn/trunk

project home : http://code.google.com/p/xedi-on-directx-11/

// edi ermawan// yogyakarta , 30122013

Written by XediXermawan

December 30, 2013 at 7:01 pm

Posted in C/C++ Diary, DirectX

Tagged with ,