Selasa, 14 Juli 2015

Teknik Masking Tanpa Tekstur Mask

Suatu pagi yang cerah...sebenarnnya masih pagi banget dan matahari belum muncul, tapi untuk membuat tetap bersemangat yah tulis aja pagi yang cerah.


Selamat pagi semuanya, rekan-rekan sekalian...kali ini ogut hanya ingin memberikan ide sederhana saja untuk membuat game 2D, di artikel terdahulu ogut pernah menulis artikel tentang teknik masking (contoh program dengan VC++ dan dengan VB .Net). Teknik masking sangat berguna untuk membuat game 2D, bagi Anda yang belum membaca artikel terdahulu ogut ulang sedikit ya, teknik masking membutuhkan dua buah tekstur yaitu tektur image dan tekstur mask, tekstru mask hanya mempunyai dua warna yaitu putih sempurna dan hitam sempurna.

Ilustrasi teknik masking dapat Anda lihat pada gambar dibawah ini. Dua buah tekstur digabung menjadi satu, sehingga tampak objek pohon seperti aslinya (warna hitam di belakang hilang)


Untuk dapat menampilkan sebuah objek seperti di atas maka Anda harus mempunyai dua buah tekstur, tekstur image harus Anda buat, tidak bisa tidak, tetapi tekstur mask dapat Anda buat secara programming. Kenapa? Karena tekstur mask hanya mempunyai dua buah warna yaitu putih dan hitam sempurna.

Contoh tekstur image  yang dibuat dari file bitmap 24 bit.


Pada artikel game engine yang pernah ogut tulis sebelumnya, trik seperti ini sebenarnya sudah ogut gunakan, jika Anda melihat source code pada saat proses loading tekstur, tidak ada proses untuk loading tekstur mask, karena tekstur mask dibuat secara programming.

Berikut fungsi yang ogut gunakan untuk membuat tekstur image dan mengkonversi menjadi tektur mask.

bool GEEmas7::CreateGETexture(char *file, unsigned int &IDImage, unsigned int &IDMask, bool BoolMask)
{
FILE *pFile = 0;            
BITMAPFILEHEADER BmpFileHeader;    
BITMAPINFOHEADER BmpInfoHeader;
unsigned char *BmpImage;

unsigned char BGR_to_RGB = 0;

//pFile = fopen(file, "rb");  
errno_t err;

err = fopen_s(&pFile, file, "rb");

//if(!fp)
if (err != 0)
{
MessageBox(NULL, file, "File Bmp tidak ditemukan, BMP Error 01", MB_OK);
return false;
}

/*if(pFile == 0)
{
MessageBox(NULL, file, "File Bmp tidak ditemukan, BMP Error 01", MB_OK);
return false;    
}*/


fread(&BmpFileHeader, sizeof(BITMAPFILEHEADER), 1, pFile);

if(BmpFileHeader.bfType != 0x4D42)
{
fclose(pFile);

MessageBox(NULL, file, "Format file bukan Bmp, BMP Error 02", MB_OK);

return false;
}

fread(&BmpInfoHeader, sizeof(BITMAPINFOHEADER), 1, pFile);

   if(BmpInfoHeader.biSizeImage == 0)
      BmpInfoHeader.biSizeImage = BmpInfoHeader.biWidth * BmpInfoHeader.biHeight * 3;

fseek(pFile, BmpFileHeader.bfOffBits, SEEK_SET);

BmpImage = (unsigned char*)malloc(BmpInfoHeader.biSizeImage);

if(!BmpImage)
{
free(BmpImage);
fclose(pFile);

MessageBox(NULL, file, "Gagal alokasi memory untuk texture, BMP Error 03", MB_OK);
return false;
}

fread(BmpImage, 1, BmpInfoHeader.biSizeImage, pFile);

fclose(pFile);

if(BmpImage == 0)
{
MessageBox(NULL, file, "Gagal membaca data Bmp, BMP Error 04", MB_OK);

return false;
}

for(int i = 0; i < (int)BmpInfoHeader.biSizeImage; i += 3)
{
BGR_to_RGB = BmpImage[i];
BmpImage[i] = BmpImage[i + 2];
BmpImage[i + 2] = BGR_to_RGB;
}

if(BmpImage == 0)
{
MessageBox(NULL, file, "Gagal membuat RGB texture, BMP Error 05", MB_OK);
return false;
}

//generate texture
glGenTextures(1, &IDImage);
glBindTexture(GL_TEXTURE_2D, IDImage);

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, BmpInfoHeader.biWidth, BmpInfoHeader.biHeight, GL_RGB, GL_UNSIGNED_BYTE, BmpImage);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BmpInfoHeader.biWidth, BmpInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, BmpImage);

/////////////////////////////////////////
//MEBUAT TEXTURE MASK
/////////////////////////////////////////
if (BoolMask)
{
//convert BmpImage jadi mask
ConvertToMask((int)BmpInfoHeader.biSizeImage, BmpImage);

//generate texture
glGenTextures(1, &IDMask);
glBindTexture(GL_TEXTURE_2D, IDMask);

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, BmpInfoHeader.biWidth, BmpInfoHeader.biHeight, GL_RGB, GL_UNSIGNED_BYTE, BmpImage);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BmpInfoHeader.biWidth, BmpInfoHeader.biHeight, 0, GL_RGB, GL_UNSIGNED_BYTE, BmpImage);
}
/////////////////////////////////////////

if(BmpImage)
{
free(BmpImage);
BmpImage = 0;
}
 
   return true;
}

Konversi tekstur image menjadi tekstur mask.

void GEEmas7::ConvertToMask(int MaskSize, unsigned char ArrayTexture[])
{
//ubah hitam sempurna jadi putih sempurna,
//dan warna object jadi hitam sempurna

//   0 hitam sempurna
// 255 putih sempurna

for (int i = 0; i < MaskSize; i++)
if (ArrayTexture[i] == 0)
ArrayTexture[i] = 255;
else
ArrayTexture[i] = 0;
}

Bagaimana rekan-rekan? Dengan trik seperti ini maka Anda akan menghemat banyak waktu, karena tekstur mask tidak perlu Anda buat dengan menggunakan tools seperti Photoshop.

Salam Hangat


Heriady
heriady.yoh@gmail.com




Artikel terkait

Membuat Game Engine Sendiri dengan Visual C++

Membuat File Bitmap 24 Bit

Warna Putih dan Hitam Sempurna

Teknik Masking dengan OpenGL 2D

Teknik Masking pada OpenTK 2D