Hari masih pagi dan matahari mulai bersinar, wah hari ini cerah tidak mendung
Pagi semua...
Setelah kita belajar cara untuk membuat Empty Project pada Visual Studio 2013 sekarang saatnya rekan-rekan belajar cara membuat program grafik OpenGL dengan menggunakan Empty Project.
Bagi rekan-rekan yang baru pertama kali membuat program grafik dengan OpenGL ogut sarankan untuk memulai dari Win32 Console Application, karena program nya sangat sederhana dan lebih mudah dipelajari (tidak bermaksud merendahkan lho, hanya saran saja).
Ok kita mulai sekarang, program yang akan kita buat akan menghasilkan tampilan seperti gambar di bawah ini. Sederhana bukan? Akan tampil sebuah kotak dan sebuah garis.
Pertama kali Anda harus membuat Empty Project di Visual Studio 2013, lalu tambahkan kode-kode berikut ini.
Pasang ini di program rekan-rekan, gunanya tinggal baca (semua kan udah pinter membaca...hehehe).
//berguna untuk memangkas library
//yang tidak terpakai
#define WIN32_LEAN_AND_MEAN
#define VC_LEANMEAN
#define VC_EXTRALEAN
Header juga harus di tambahkan (ini permintaan VC++ lho, bukan aku yang minta, jadi rekan-rekan jangan marah yah).
//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
Habis itu kita tambahin juga Library (supaya adil library juga harus tampil, ntar pada irian lagi).
//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
Berikutnya ada 4 fungsi yang harus rekan tambahin, 4 fungsi ini ngak bisa kita diskon, harus ada semuanya, kita belajar satu-satu yah....
Fungsi Pertama, ada keterangannya lho tinggal baca aja, tapi jangan asal baca nanti tidak paham.
//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;
}
//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 Kedua, nih juga ada keterangannya, jika sulit untuk dipahami sabar aja, orang sabar di sayang ama Tuhan.
//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 ketiga, ribet ya banyak angka-angka, ngak usah dihapalin, ogut juga ngak hapal sama fungsi ini, yang penting ngerti.
//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);
}
Dan yang terakhir fungsi untuk menampilan objek grafik ke layar monitor, selesai deh semuanya. Pemrograman dengan Empty Project emang lebih panjang, tetapi percayalah, ini lebih berguna jika rekan-rekan ingin naik ke tingkat selajutnya.
//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
//...........................
//Kotak
glBegin(GL_LINE_LOOP);
//titik kiri bawah
glVertex2d(-300.0, -100.0);
//titik kanan bawah
glVertex2d(200.0, -100.0);
//titik kanan atas
glVertex2d(200.0, 100.0);
//titik kiri atas
glVertex2d(-300.0, 100.0);
glEnd();
//garis miring
glBegin(GL_LINE_LOOP);
//titik atas
glVertex2d(300.0, 400.0);
//titik bawah
glVertex2d(400.0, -200.0);
glEnd();
//fungsi swapbuffer harus dipasang pada akhir Display_Grafik()
SwapBuffers(My_HDC_Global);
}
Selamat deh untuk rekan-rekan karena telah melewati babak berikutnya, ini ogut sertakan kode program nya secara lengkap, bisa copy paste dan terserah rekan-rekan mau kasih author ato tidak ngak dosa koq.
//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;
//+++++++++++++++++++++++++++++++++++++++++++
//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();
//+++++++++++++++++++++++++++++++++++++++++++
//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;
}
//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);
}
//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
//...........................
//Kotak
glBegin(GL_LINE_LOOP);
//titik kiri bawah
glVertex2d(-300.0, -100.0);
//titik kanan bawah
glVertex2d(200.0, -100.0);
//titik kanan atas
glVertex2d(200.0, 100.0);
//titik kiri atas
glVertex2d(-300.0, 100.0);
glEnd();
//garis miring
glBegin(GL_LINE_LOOP);
//titik atas
glVertex2d(300.0, 400.0);
//titik bawah
glVertex2d(400.0, -200.0);
glEnd();
//fungsi swapbuffer harus dipasang pada akhir Display_Grafik()
SwapBuffers(My_HDC_Global);
}
Salam Sukses Selalu buat rekan-rekan, terima kasih telah membaca artikel ini semoga bermanfaat.
Heriady
heriady.yoh@gmail.com
Link download kode program dapat Anda klik disini nih, ngak capek ngetik lagi tinggal run aja
Artikel terkait
Cara Membuat Win32 Console Application
Cara Membuat Empty Project
Program OpenGL 2D Sederhana untuk pemula
Tidak ada komentar:
Posting Komentar