Xedi.Xermawan's Blog

personal-technical blog

Posts Tagged ‘directx

Rendering animated GIF file

with 3 comments

gif file ( http://en.wikipedia.org/wiki/Graphics_Interchange_Format ) is very popular format , you can share funny animation, emotion, a splash for ads, etc. All web browser support this format. do you interested in how game or application (non-web) render animated gif ? . here my experiment result :

( set video quality to 480p  )

info :
rendering : DirectX 11
language : c/c++
GIF decoder : libnsgif

Written by XediXermawan

May 30, 2014 at 12:31 am

Posted in C/C++ Diary

Tagged with , , ,

Recent spare time projects

leave a comment »

I have been working on these projects in my spare time quite while ( like I work on it when I want work on it  :p )., but recently I’m disappointed with my progress ( apparently I’m busy and have difficulty when creating graphics assets by myself ). so I decided to upload source code to google code in case I’m interested again next time .There are 2 projects :

[1] unknown project 1. very simple game, almost done. keyword : C/C++,DirectX, Desktop App,Windows Phone 8

home project : https://code.google.com/p/my-fifteen-puzzle-dx/

svn link : https://my-fifteen-puzzle-dx.googlecode.com/svn/trunk

[2] unknown project 2 . also very simple game ( I like simple thing ). puzzle. gameplay complete. keyword : C/C++,DirectX, Desktop App, Windows Phone 8.

home project : https://code.google.com/p/proximity-game-clone2-dx/

svn link : https://proximity-game-clone2-dx.googlecode.com/svn/trunk

both of them actually same app I had made before . I rewrite again these projects using entirely new c/c++ code and using DirectX as graphics API. I also implemented some design pattern there. In case you are interested , check it out 🙂

game screenhoot running on windows phone 8 device
fiveteen_wp8

Written by XediXermawan

May 13, 2014 at 11:55 am

[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 ,

[2] on directx 11 : sending data to shader

leave a comment »

Bagaimana mengirim data dari code CPU ( c++ code ) ke code GPU ( hlsl ) ?. Di program sebelumnya, beberapa data yang di kirim ke shader :

  • vertex dan index , direpresentasikan dengan D3D11Buffer , di set ke shader dengan IASetVertexBuffers, dan IASetIndexBuffers. prefix IA : buffer ini di set ke input assembler stage dan dapat diakses di VS .
  • model, view, projection matrix,  direpresentasikan dengan D3D11Buffer, di set ke shader dengan VSSetConstantBuffers. prefix VS,karena buffer ini akan dipakai sebagai global variable di vertex shader .
  • texture, berupa shader resource view, di set ke shader dengan PSSetShaderResources. prefix PS, texture hanya dipakai di pixel shader stage.

model, view projection matrik dibuat dengan bind flag D3D11_BIND_CONSTANT_BUFFER . mvp disini nilainya tidak konstant, tapi berubah-ubah per-frame. lalu kenapa bind flag nya ‘constant buffer’?, hal ini yang membuat saya bertanya diawal2. “constant buffer” disini, dimaksudkan nilainya tetap konstant per 1 proses draw command. namun di draw command selanjutnya bisa berubah. Jika kita ingin memiliki variable yang “semacam” mvp matrix ( berubah-ubah per-frame, dan dapat diakses di shader –vs,ps) , maka kita harus membuat constant buffer semacam ini. sebagai percobaan yang bisa dilihat hasilnya langsung, saya ingin mengirim data ke pixel shader untuk mengubah saturation-desaturation dari texture kubus di program sebelumnya. di c++ code saya perlu struct untuk meng-hold data ini :

struct color_constantbuffer
{
DirectX::XMFLOAT4 saturation;
DirectX::XMFLOAT4 luminance;
};

sedangkan di pixel shader, saya perlu membuat constant buffer, dengan kata kunci cbuffer :

cbuffer ColorConstantBuffer
{
float4 saturation;
float4 luminance;
};

next step, perlu dibuat d3dbuffer untuk menyimpan data : ( m_ColorConstantBuffer  adalah ID3D11Buffer* )

D3D11_BUFFER_DESC ColorConstBufferDesc;
ColorConstBufferDesc.Usage = D3D11_USAGE_DYNAMIC;
ColorConstBufferDesc.ByteWidth = sizeof(color_constantbuffer);
ColorConstBufferDesc.BindFlags = D3D11_BIND_CONSTANT_BUFFER;
ColorConstBufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE;
ColorConstBufferDesc.MiscFlags = 0;
ColorConstBufferDesc.StructureByteStride = 0;

hr = m_Device->CreateBuffer( &ColorConstBufferDesc , NULL , &m_ColorConstantBuffer );

dan untuk memberi tahu gpu, kalau buffer ini akan dipakai di pixel shader stage , perlu di set dengan command :

m_DevContext->PSSetConstantBuffers( 0,1,&m_ColorConstantBuffer);

lalu bagaimana cara meng-update color constant buffer ini ?.Untuk mvp constant buffer dipakai UpdateSubresource. Cara lain adalah menggunakan fungsi Map/Unmap . Bedanya dengan UpdateSubresource, Map/Unamp, bisa read-write data ke gpu, sedangkan UpdateSubresource hanya write saja. meng-update color constant buffer dengan Map/Unmap :

D3D11_MAPPED_SUBRESOURCE mappedResource;
color_constantbuffer* colvalue;
HRESULT hr = m_DevContext->Map(m_ColorConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
assert( hr == S_OK );
// get ptr data
colvalue = (color_constantbuffer*)mappedResource.pData;
// set data
colvalue->luminance = DirectX::XMFLOAT4( );  //  <— set new value here
colvalue->saturation = DirectX::XMFLOAT4( );  //  <— set new value here
// Unlock the constant buffer.
m_DevContext->Unmap(m_ColorConstantBuffer, 0);

di pixel shader, variabel luminance&saturation dipakai menghitung saturaion/desaturation.  ( Simple_PS_02.hlsl )

float4 main(PixelShaderInput input) : SV_TARGET
{
// PixelShaderInput.color input doesn’t used in this shader
float4 texColorOut;
// Sample the pixel color from the texture using the sampler at this texture coordinate location.
texColorOut = shaderTexture.Sample(SampleType, input.tex);
float3 luminanceVal = dot( texColorOut, float3(luminance.x,luminance.y,luminance.z));
float4 finalCol = float4( lerp( luminanceVal , texColorOut, saturation ),1.0f);
finalCol.z = texColorOut.z;
return finalCol;
}

note : rumus menghitung saturation/desaturation , nemu di SINI

agar lebih interaktif,  di percobaan ini saya menambahkan input untuk user melalui keyboard yang memungkinkan user mengubah saturation dan luminance.

tombol 1-4 : saturation

tombol 5-8: luminance

hasil akhir program percobaan ini: menggambar kubus, dimana warna texture bisa diubah-ubah warnanya dengan mengubah saturation. input lain :

u-i : pitch

o-p: roll

k-l : yaw

n-m : zoom in/out

screenshoot output program (klik gambar untuk memperbesar *) :

cube_rot_frog

full source code & project ( vs 2012 desktop ) . ( xedi_on_directx11___2___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/

// edie // nganjuk  , 27122013

Written by XediXermawan

December 27, 2013 at 4:50 pm

Posted in C/C++ Diary, DirectX

Tagged with ,

[1] on directx 11 : texturing

leave a comment »

Di program sebelumnya informasi gambar/ vertex data di-representasikan dengan data struct dibawah ini :  (vertex_type.hpp)

struct vertex_type
{
DirectX::XMFLOAT3 position;
DirectX::XMFLOAT3 color;
};

struct ini ber-asosiasi dengan shader code : ( Simple_VS.hlsl )

struct VertexShaderInput
{
float3 pos : POSITION;
float3 color : COLOR0;
};

dengan sedikit modifikasi, kita bisa menambahkan texture ke vertex data untuk kubus :

vertex_type.hpp

Simple_VS.hlsl

Simple_PS.hlsl

structvertex_type{DirectX::XMFLOAT3 position;DirectX::XMFLOAT3 color;DirectX::XMFLOAT2 texcoord; // ← added

};

struct VertexShaderInput{float3 pos : POSITION;float3 color : COLOR0;float2 tex : TEXCOORD0;// ← added

};

 

struct PixelShaderInput{float4 pos : SV_POSITION;float3 color : COLOR0;float2 tex:TEXCOORD0;//← added

};

Karena informasi vertex berubah, data vertex juga harus diubah,  program sekarang harus mengirim : position (float3), color(float3), dan texture coordinate(float2) ke GPU .position adalah jelas koordinat x,y,z di space 3d, color adalah r,g,b di sini, sedangkan texture coordinate, bisa dijelaskan dengan gambar sebagai berikut :

coord_textured

koordinat front face cube :
{XMFLOAT3(-1.0f, -1.0f, -1.0f),XMFLOAT3(0.0f, 0.0f, 0.0f), XMFLOAT2(0.0f, 1.0f)},
{XMFLOAT3(-1.0f, 1.0f, -1.0f),XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(0.0f, 0.0f)},
{XMFLOAT3( 1.0f, 1.0f, -1.0f),XMFLOAT3(1.0f, 0.0f, 0.0f), XMFLOAT2(1.0f, 0.0f)},
{XMFLOAT3( 1.0f, -1.0f, -1.0f),XMFLOAT3(0.0f, 0.0f, 1.0f), XMFLOAT2(1.0f, 1.0f)},
dari gambar, texture akan menutup triangle di koordinat yang bersesuaian.
Langkah selanjutnya adalah mengubah input layout, untuk memberi tahu GPU kalau aplikasi akan mengirim layout data seperti ini :

 D3D11_INPUT_ELEMENT_DESC inputVertexDesc[3]; // position , color, texture coord
 inputVertexDesc[0].SemanticName = "POSITION";
 inputVertexDesc[0].SemanticIndex = 0;
 inputVertexDesc[0].Format = DXGI_FORMAT_R32G32B32_FLOAT;
 inputVertexDesc[0].InputSlot = 0;
 inputVertexDesc[0].AlignedByteOffset = 0;
 inputVertexDesc[0].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
 inputVertexDesc[0].InstanceDataStepRate = 0;

inputVertexDesc[1].SemanticName = "COLOR";
 inputVertexDesc[1].SemanticIndex = 0;
 inputVertexDesc[1].Format = DXGI_FORMAT_R32G32B32_FLOAT;
 inputVertexDesc[1].InputSlot = 0;
 inputVertexDesc[1].AlignedByteOffset = 12; //D3D11_APPEND_ALIGNED_ELEMENT;
 inputVertexDesc[1].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
 inputVertexDesc[1].InstanceDataStepRate = 0;

inputVertexDesc[2].SemanticName = "TEXCOORD";  // added
 inputVertexDesc[2].SemanticIndex = 0;
 inputVertexDesc[2].Format = DXGI_FORMAT_R32G32B32_FLOAT;
 inputVertexDesc[2].InputSlot = 0;
 inputVertexDesc[2].AlignedByteOffset =24; //D3D11_APPEND_ALIGNED_ELEMENT;
 inputVertexDesc[2].InputSlotClass = D3D11_INPUT_PER_VERTEX_DATA;
 inputVertexDesc[2].InstanceDataStepRate = 0;
 int numElement = sizeof( inputVertexDesc ) / sizeof ( inputVertexDesc[0] );
 hr = m_Device->CreateInputLayout
 ( inputVertexDesc, numElement , vs_ba , vs_ba_len , &m_InputLayout );

step selanjutnya kita perlu menyiapkan data texture. Di project saya menambahkan DDSTextureLoader class ( class helper untuk me-load texture dari file ).

CreateDDSTextureFromFile( m_Device , L”../data/textures/texture_01.DDS”, nullptr, &m_TextureShaderResView, MAXSIZE_T);

dan data texture ini kita kirim ke gpu sebelum eksekusi gambar terjadi :

m_DevContext->PSSetShaderResources(0, 1, &m_TextureShaderResView);
m_DevContext->DrawIndexed(36, 0, 0);

Hasil eksekusi program :

cube_rot_textured

full source code & project ( vs 2012 desktop ) . ( xedi_on_directx11___1___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/

// edie // nganjuk , 26122013

Written by XediXermawan

December 26, 2013 at 4:44 pm

Posted in C/C++ Diary, DirectX

Tagged with , ,