Sabtu, 23 Mei 2015

Teknik Masking dengan OpenGL 2D

Suatu subuh dimana ayam tetangga belum berkokok karena masih nyenyak tidur

Pagi Semuanya, eh salah Subuh Semuanya...

Pada hari ini aku akan melanjukan programming tentang tekstur yang telah dibahas sebelumnya. Teknik masking menggunakan file bitmap 24 bit sebagai teksturnya, seperti contoh gambar di bawah ini.


Warna putih dan hitam sempurna penjelasannya dapat rekan-rekan baca pada link berikut ini. Dari gambar di atas rekan-rekan dapat melihat, untuk membuat program teknik masking diperlukan dua buah image bitmap 24 bit. Satu image berlatar belakang putih sempurna dan satu lagi berlatar belakang hitam sempurna. Jika kedua image disatukan maka akan menghasilkan sebuah image baru yang hilang warna latar belakangnya.

Proses penghilangan latar belakang ini yang disebut dengan teknik masking, seperti contoh gambar dibawah ini.


Wow keren ya (yang keren sebenarnya OpenGL nya), Teknik ini amat sangat berguna jika rekan-rekan ingin membuat game 2D, karena dengan teknik ini rekan-rekan bisa menampilkan objek-objek game 2D seperti pesawat, bom, peluruh, tank dan sebagainya.

Untuk membuat program teknik masking rekan-rekan harus paham terlebih dahulu tentang cara membuat tekstur. Jika sudah paham maka rekan-rekan bisa melanjutkannya.

Pertama siapkan dua buah image bitmap 24 bit, satu berlatar belakang putih sempurna (texture_mask) dan satu berlatar belakang hitam sempurna (texture_image), lalu load kedua image tersebut dan konversi menjadi tekstur.

//load file bitmap 24 bit
bool Load_Texture()
{
glEnable(GL_TEXTURE_2D);

if ((texture_mask = Create_Texture("Bmp_Files/texture_mask.bmp")) == NULL)
return false;

if ((texture_image = Create_Texture("Bmp_Files/texture_image.bmp")) == NULL)
return false;

...
        ...
        ...

return true;
}

Kedua, tampilkan kedua tekstur secara berurutan dengan kode seperti di bawah ini. Jadi deh maskingnya.

 //Teknik masking,
//berguna untuk menampilkan object game 2D
//pada sistem koordinat kartesius 2D

//tampilkan texture mask
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR, GL_ZERO);

glBindTexture(GL_TEXTURE_2D, texture_mask);
glBegin(GL_POLYGON);
glTexCoord2d(0.0, 0.0);
glVertex2d(-300.0, -350.0);

glTexCoord2d(1.0, 0.0);
glVertex2d(300.0, -350.0);

glTexCoord2d(1.0,1.0);
glVertex2d(300.0, 350.0);

glTexCoord2d(0.0, 1.0);
glVertex2d(-300.0, 350.0);
glEnd();

//tampilkan texture image
glBlendFunc(GL_ONE, GL_ONE);

glBindTexture(GL_TEXTURE_2D, texture_image);
glBegin(GL_POLYGON);
glTexCoord2d(0.0, 0.0);
glVertex2d(-300.0, -350.0);

glTexCoord2d(1.0, 0.0);
glVertex2d(300.0, -350.0);

glTexCoord2d(1.0, 1.0);
glVertex2d(300.0, 350.0);

glTexCoord2d(0.0, 1.0);
glVertex2d(-300.0, 350.0);
glEnd();

glDisable(GL_BLEND);

Nah ini dia kode program lengkapnya, silahkan di copy paste atau download langsung projectnya di akhir artikel ini.

//berguna untuk memangkas library
//yang tidak terpakai
#define WIN32_LEAN_AND_MEAN  
#define VC_LEANMEAN  
#define VC_EXTRALEAN      

//include yang harus disertakan
#include<windows.h>
#include<stdio.h>        
#include<stdlib.h>
#include<mmsystem.h>

//include khusus OpenGL
#include<gl/gl.h>              
#include<gl/glu.h>
#include "glaux/glaux.h" //header ini ada di dalam folder GLAUX

//library untuk OpenGL
#pragma comment(lib, "opengl32.lib")
#pragma comment(lib, "glu32.lib")
#pragma comment(lib, "GLAUX/glaux.lib") //library ini ada di dalam folder GLAUX

//Variable global yang dipakai untuk program ini
HDC My_HDC_Global;

//set tinggi dan lebar untuk window screen
unsigned int tinggi_window_Screen = 600;
unsigned int lebar_window_Screen = 800;

//penempatan posisi window screen di monitor
unsigned int X_window_Screen = 150;
unsigned int Y_window_Screen = 50;

//berguna untuk setup pixel
//dengan sistem koordinat kartesius 2D
double Xmax = 800.0;
double Ymax = 600.0;

//variable Texture
unsigned int texture_mask;
unsigned int texture_image;
unsigned int texture_merah;

//+++++++++++++++++++++++++++++++++++++++++++
//untuk membuat program grafik dengan OpenGL
//hanya dibutuhkan empat buah fungsi, dengan
//WinMain sebagai fungsi utama (WinMain 1 fungsi tambah 3 fungsi dibawah ini jadi 4 semuanya)
LRESULT CALLBACK My_WindowProc(HWND hwnd_p, UINT message_p, WPARAM wparam_p, LPARAM lparam_p);
void Window_Pixel_Format(HDC hdc_GPF_p);
void Display_Grafik();

unsigned int Create_Texture(char *filename);
bool Load_Texture();

//+++++++++++++++++++++++++++++++++++++++++++

//fungsi yang dipanggil pertama kali
//oleh Operating system Windows, pada
//saat program dijalankan
int WINAPI WinMain(HINSTANCE hinstance_p, HINSTANCE hprevinstance_p, LPSTR lpcmdline_p, int nshowcmd_p)
{
MSG My_MSG;
WNDCLASSEX My_WNDCLASSEX;
HWND My_HWND;
bool My_MainLoop = false;

//deklarasi variable untuk membuat window
My_WNDCLASSEX.cbSize = sizeof(WNDCLASSEX);
My_WNDCLASSEX.style = CS_HREDRAW | CS_VREDRAW;

//My_WindowProc adalah fungsi yang kita buat
//untuk memproses message-message,
//fungsi ini yang terus menerus akan dipanggil
//oleh fungsi WinMain, sehingga harus kita
//daftarkan di bawah ini
My_WNDCLASSEX.lpfnWndProc = My_WindowProc;

My_WNDCLASSEX.cbClsExtra = 0;
My_WNDCLASSEX.cbWndExtra = 0;
My_WNDCLASSEX.hInstance = hinstance_p;
My_WNDCLASSEX.hIcon = LoadIcon(NULL, IDI_WINLOGO);
My_WNDCLASSEX.hCursor = LoadCursor(NULL, IDC_WAIT);
My_WNDCLASSEX.hbrBackground = NULL;
My_WNDCLASSEX.lpszMenuName = NULL;
My_WNDCLASSEX.lpszClassName = "MyOpenGL";
My_WNDCLASSEX.hIconSm = LoadIcon(NULL, IDI_WINLOGO);

//register window Class
//jika terjadi error program dihentikan
if (!RegisterClassEx(&My_WNDCLASSEX))
{
MessageBox(NULL,
"Register Window Class Failed", "Window Error", MB_OK);
return 0;
}

//jika register window class berhasil
//lanjutkan dengan create window
My_HWND = CreateWindowEx(
NULL,
"MyOpenGL",
"Heriady Blog heriadyblog.blogspot.com (Esc to quit)",
NULL,
X_window_Screen,
Y_window_Screen,
lebar_window_Screen,
tinggi_window_Screen,
NULL,
NULL,
hinstance_p,
NULL);

//jika window tidak bisa di-create
//program dihentikan
if (!My_HWND)
{
MessageBox(NULL,
"Failed to Create Window", "Window Error", MB_OK);
return 0;
}

//load all texture here
if (!Load_Texture())
return 0;

//jika window bisa di-create
//tampilkan window ke monitor
ShowWindow(My_HWND, SW_SHOW);
UpdateWindow(My_HWND);

//Looping utama
while (!My_MainLoop)
{
//proses message dari antrian
PeekMessage(&My_MSG, 0, 0, 0, PM_REMOVE);

//selama tidak ada message 'Quit'
//looping akan terus berjalan
if (My_MSG.message != WM_QUIT)
{
//panggil fungsi untuk render window
//disini
Display_Grafik();

//translate Virtual key message,
//menjadi chararcter message dan
//buang message yang sudah diproses
TranslateMessage(&My_MSG);
DispatchMessage(&My_MSG);
}
else
//jika message = 'Quit'
//keluar dari looping
My_MainLoop = true;


} //while (!My_MainLoop)

//unregister window class
UnregisterClass("MyOpenGL", My_WNDCLASSEX.hInstance);

//akhiri program
return (int)My_MSG.wParam;
}

//fungsi yang dipanggil oleh WinMain
//untuk memproses message-message
LRESULT CALLBACK My_WindowProc(HWND hwnd_p, UINT message_p, WPARAM wparam_p, LPARAM lparam_p)
{
static HGLRC My_HGLRC;
static HDC My_HDC;

//pada saat window dibuat pertama kali
//kondisi if di bawah memenuhi
if (message_p == WM_CREATE)
{
My_HDC = GetDC(hwnd_p);
My_HDC_Global = My_HDC;

//pada saat pertama kali dibuat
//window screen harus di setup pixel
//agar bisa dibuat untuk tampilan grafik
Window_Pixel_Format(My_HDC);

My_HGLRC = wglCreateContext(My_HDC);
wglMakeCurrent(My_HDC, My_HGLRC);

return 0;
}

//pada saat program hendak keluar
//kondisi if di bawah memenuhi
if (message_p == WM_DESTROY)
{
wglMakeCurrent(My_HDC, NULL);
wglDeleteContext(My_HGLRC);
PostQuitMessage(0);

return 0;
}

//untuk saat window dibuat pertama kali atau
//window diubah ukurannya.
//pada program ini ukuran window
//tidak bisa diubah, tetapi kondisi if
//di bawah harus tetap di pasang
if (message_p == WM_SIZE)
{
//fungsi OpenGL untuk set
//tinggi dan lebar window screen
glViewport(0, 0, lebar_window_Screen, tinggi_window_Screen);

glMatrixMode(GL_PROJECTION);
glLoadIdentity();

//fungsi untuk membuat sistem
//koordinat kartesius 2D
// -X = -800, X = +800 dan,
// -Y = -600, Y = +600
gluOrtho2D(-Xmax, Xmax, -Ymax, Ymax);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();

//warna latar belakang hitam
glClearColor(0.0, 0.0, 0.0, 0.0);

return 0;
}

//tombol ESC ditekan
//untuk keluar dari program
if ((message_p == WM_KEYDOWN) && (wparam_p == VK_ESCAPE))
{
//fungsi untuk mengirimkan
//message WM_QUIT
PostQuitMessage(0);

return 0;
}

//return kembali nilai LRESULT
return (DefWindowProc(hwnd_p, message_p, wparam_p, lparam_p));
}

//fungsi untuk setup pixel, yang
//dipakai untuk program grafik,
//fungsi ini harus ada jika hendak membuat
//program grafik
void Window_Pixel_Format(HDC hdc_GPF_p)
{
int My_Pixel_Format;

static PIXELFORMATDESCRIPTOR My_PFD =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
16,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
16,
0,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};

My_Pixel_Format = ChoosePixelFormat(hdc_GPF_p, &My_PFD);

SetPixelFormat(hdc_GPF_p, My_Pixel_Format, &My_PFD);
}

//load file bitmap 24 bit
bool Load_Texture()
{
glEnable(GL_TEXTURE_2D);

if ((texture_mask = Create_Texture("Bmp_Files/texture_mask.bmp")) == NULL)
return false;

if ((texture_image = Create_Texture("Bmp_Files/texture_image.bmp")) == NULL)
return false;

if ((texture_merah = Create_Texture("Bmp_Files/text_merah.bmp")) == NULL)
return false;

return true;
}

//digunakan untuk membuat tekstur dari file bitmap 24 bit
unsigned int Create_Texture(char *filename)
{
AUX_RGBImageRec *My_Texture;
unsigned int My_IDTexture;

My_Texture = auxDIBImageLoad(filename);

if (My_Texture != NULL)
{
glGenTextures(1, &My_IDTexture);

glBindTexture(GL_TEXTURE_2D, My_IDTexture);

glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);

gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB,
My_Texture->sizeX, My_Texture->sizeY,
GL_RGB, GL_UNSIGNED_BYTE,
My_Texture->data);

glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB,
My_Texture->sizeX, My_Texture->sizeY,
0, GL_RGB, GL_UNSIGNED_BYTE,
My_Texture->data);

free(My_Texture);

return My_IDTexture;
}

return NULL;
}

//fungsi yang dipakai untuk menampilkan
//semua object(Polygon) yang akan kita buat
//pada window screen
void Display_Grafik()
{
//clear buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

//...........................
//display object  di sini
//...........................

//latar belakang
glBindTexture(GL_TEXTURE_2D, texture_merah);
glBegin(GL_POLYGON);
//titik kiri bawah
glTexCoord2d(0.0, 0.0);
glVertex2d(-Xmax, -Ymax);
//titik kanan bawah
glTexCoord2d(1.0, 0.0);
glVertex2d(Xmax, -Ymax);
//titik kanan atas
glTexCoord2d(1.0, 1.0);
glVertex2d(Xmax, Ymax);
//titik kiri atas
glTexCoord2d(0.0, 1.0);
glVertex2d(-Xmax, Ymax);
glEnd();

//Teknik masking,
//berguna untuk menampilkan object game 2D
//pada sistem koordinat kartesius 2D

//tampilkan texture mask
glEnable(GL_BLEND);
glBlendFunc(GL_DST_COLOR, GL_ZERO);

glBindTexture(GL_TEXTURE_2D, texture_mask);
glBegin(GL_POLYGON);
glTexCoord2d(0.0, 0.0);
glVertex2d(-300.0, -350.0);

glTexCoord2d(1.0, 0.0);
glVertex2d(300.0, -350.0);

glTexCoord2d(1.0,1.0);
glVertex2d(300.0, 350.0);

glTexCoord2d(0.0, 1.0);
glVertex2d(-300.0, 350.0);
glEnd();

//tampilkan texture image
glBlendFunc(GL_ONE, GL_ONE);

glBindTexture(GL_TEXTURE_2D, texture_image);
glBegin(GL_POLYGON);
glTexCoord2d(0.0, 0.0);
glVertex2d(-300.0, -350.0);

glTexCoord2d(1.0, 0.0);
glVertex2d(300.0, -350.0);

glTexCoord2d(1.0, 1.0);
glVertex2d(300.0, 350.0);

glTexCoord2d(0.0, 1.0);
glVertex2d(-300.0, 350.0);
glEnd();

glDisable(GL_BLEND);

//fungsi swapbuffer harus dipasang pada akhir Display_Grafik()
SwapBuffers(My_HDC_Global);
}

Bagimana masih bingung, tentu tidak, karena pada prinsipnya kedua tekstur ditampilkan secara berurutan ditempat yang sama (kotak / poligon).

Sampai disini dulu penjelasan tentang teknik masking, lain kali ogut akan menjelaskan tentang programming yang lain yang tidak kalah bermanfaatnya, selamat belajar.

Salam Sukses kepada rekan-rekan semua


Heriady
heriady.yoh@gmail.com


Download program ini dapat Anda klik disini, sehingga ngak capek ngetik-ngetik lagi.


Artikel tekait
Cara membuat file bitmap 24 bit
Warna putih dan hitam sempurna
Tekstur programming dengan OpenGL