Rabu, 27 Mei 2015

Membuat Objek Pipa 3D Wire / Kawat

Menjelang subuh (bener ini subuh kalo ngak percaya tanya deh ama ayam tetangga, dia berkokok melulu)...


Pagi rekan-rekan...
Kali ini aku akan membahas tentang cara membuat objek pipa 3D dengan memanfaatkan matematika trigonometri.


Hasil dari program ini dapat rekan-rekan lihat pada gambar di atas, dan objek pipa 3D ini dipakai untuk membuat objek tangki air 3D yang sebelumnya pernah ogut posting.

Ok ngak usah nunggu lagi kita langsung aja (eh ayamnya udah berhenti berkokok, padahal asyik juga dengernya).

Sekarang serius nih...


Gambar di atas adalah gambar dari jaring-jaring kawat (wire) sebuah pipa yang hendak kita buat, perhatikan jumlah polygon yang dibutuhkan untuk membuat pipa tersebut, ada 14 buah polygon.


Gambar 2 adalah gambar pipa yang berbentuk wire dilihat dari sumbu y, angka 1 sampai dengan 12 adalah polygon-polygon yang hendak dibuat, dan aku memberi nama polygon-polygon tersebut sesuai dengan urutan 1 sampai 12 agar rekan-rekan mudah untuk mengerti.


Gambar 3 adalah gambar pipa wire dengan urutan array untuk menyimpan vertex-vertex-nya. Dari gambar 2 dan 3 dapat diketahui bahwa polygon 1 vertex-vertex-nya disimpan pada urutan array ke-0, 1, 2, 3, polygon 2 vertex-vertex-nya disimpan pada urutan array 2, 3, 4, 5, dan seterusnya. Alas pipa vertex-vertex-nya disimpan dengan urutan array 1, 2, 5, 6, 9, 10, 13, 14, 17, 18, 21, 22, tutup pipa vertex-vertex-nya disimpan dengan urutan array 0, 3, 4, 7, 8, 11, 12, 15, 16, 19, 20, 23.

Sekarang setelah semua bagian-bagian dari pipa telah dimengerti, selanjutnya akan dibahas perhitungan matematika untuk menentukan nilai vertex-vertex dari pipa.


Untuk membuat pipa agar fleksibel diperlukan hanya dua buah variabel yaitu jari-jari pipa (R) dan tinggi pipa.
Pada gambar 4 tampak sebuah polygon 1 dari pipa yang dibentuk dari vertex ke-0, 1, 2, 3 pada urutan array (vertex ke-1 dan ke-2 tidak tampak pada gambar 4). Dari gambar di atas dapat dihitung bahwa array ke-0 vertex-vertex-nya akan diisi dengan:

X = R Cos 0°
Y = 0.5 * tinggi
Z = R Sin 0°

Array ke-1 vertex-vertex-nya akan diisi dengan:

X = R Cos 0°
Y = -0.5 * tinggi
Z = R Sin 0°

Array ke-2 vertex-vertex-nya akan diisi dengan:

X = R Cos 30°
Y = -0.5 * tinggi
Z = R Sin -30°

Array ke-3 vertex-vertex-nya akan diisi dengan:

X = R Cos 30°
Y = 0.5 * tinggi
Z = R Sin -30°

Dari perhitungan di atas dapat dibuat pola yang tetap untuk menghitung semua nilai vertex 12 polygon sisi samping dari pipa wire, sudut sebesar 30° didapat dari 360° / 12 = 30°, 360° adalah jumlah sudut untuk satu lingkaran penuh, sedangkan 12 didapat dari jumlah polygon sisi samping pipa, sehingga untuk masing-masing polygon mempunyai perbedaan sudut secara berurutan sebesar 30°.

Pada array ke-2 dan ke-3 terlihat bahwa sudut yang dipakai bernilai negatif(-) 30°, hal ini dikarenakan vertex-vertex tersebut terletak pada sumbu –z(negatif) sehingga hasil akhir perhitungan harus bernilai negatif. Berikut tabel yang berisi perhitungan semua vertex-vertex untuk membuat pipa 14 polygon:


Perhatikan isi tabel 1 pada kolom ‘Vertex Textfile’, untuk sub kolom ‘X’ dan ‘Z’ yang disimpan pada textfile adalah sudut-sudut yang dibentuk oleh polygon-polygon pipa, dengan menyimpan sudut-sudut polygonnya akan sangat mudah untuk menghtung vertex-vertex polygon.

void loadPipa(Vertex read_pipa[24], float jari, float tinggi)
{
    int i = 0;
    double temp_sudut;
    double pi = 3.1415926535;

    ifstream pipaDat;

    cek_error_load = true;

    pipaDat.open("TXT_files/pipa_vertex.txt");

    if (!pipaDat)
    {
        //printf("Error loading pipa_vertex.txt \n");
        cek_error_load = false;
        exit(0);
    }

    while (!pipaDat.eof())
    {
        pipaDat >> read_pipa[i].VX >> read_pipa[i].VY >> read_pipa[i].VZ;
        i++;
    }


    for (i = 0; i < 24; i++)
    {
        temp_sudut = read_pipa[i].VX;
        temp_sudut = (temp_sudut / 180) * pi;
        read_pipa[i].VX = jari * (float)cos(temp_sudut);

        read_pipa[i].VY = read_pipa[i].VY * tinggi;

        temp_sudut = read_pipa[i].VZ;
        temp_sudut = (temp_sudut / 180) * pi;
        read_pipa[i].VZ = jari * (float)sin(temp_sudut);
    }
}

void pipa_wire(Vertex read_pipa[24])
{
    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[0].VX, read_pipa[0].VY, read_pipa[0].VZ);
    glVertex3f(read_pipa[1].VX, read_pipa[1].VY, read_pipa[1].VZ);
    glVertex3f(read_pipa[2].VX, read_pipa[2].VY, read_pipa[2].VZ);
    glVertex3f(read_pipa[3].VX, read_pipa[3].VY, read_pipa[3].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[2].VX, read_pipa[2].VY, read_pipa[2].VZ);
    glVertex3f(read_pipa[3].VX, read_pipa[3].VY, read_pipa[3].VZ);
    glVertex3f(read_pipa[4].VX, read_pipa[4].VY, read_pipa[4].VZ);
    glVertex3f(read_pipa[5].VX, read_pipa[5].VY, read_pipa[5].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[4].VX, read_pipa[4].VY, read_pipa[4].VZ);
    glVertex3f(read_pipa[5].VX, read_pipa[5].VY, read_pipa[5].VZ);
    glVertex3f(read_pipa[6].VX, read_pipa[6].VY, read_pipa[6].VZ);
    glVertex3f(read_pipa[7].VX, read_pipa[7].VY, read_pipa[7].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[6].VX, read_pipa[6].VY, read_pipa[6].VZ);
    glVertex3f(read_pipa[7].VX, read_pipa[7].VY, read_pipa[7].VZ);
    glVertex3f(read_pipa[8].VX, read_pipa[8].VY, read_pipa[8].VZ);
    glVertex3f(read_pipa[9].VX, read_pipa[9].VY, read_pipa[9].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[8].VX, read_pipa[8].VY, read_pipa[8].VZ);
    glVertex3f(read_pipa[9].VX, read_pipa[9].VY, read_pipa[9].VZ);
    glVertex3f(read_pipa[10].VX, read_pipa[10].VY, read_pipa[10].VZ);
    glVertex3f(read_pipa[11].VX, read_pipa[11].VY, read_pipa[11].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[10].VX, read_pipa[10].VY, read_pipa[10].VZ);
    glVertex3f(read_pipa[11].VX, read_pipa[11].VY, read_pipa[11].VZ);
    glVertex3f(read_pipa[12].VX, read_pipa[12].VY, read_pipa[12].VZ);
    glVertex3f(read_pipa[13].VX, read_pipa[13].VY, read_pipa[13].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[12].VX, read_pipa[12].VY, read_pipa[12].VZ);
    glVertex3f(read_pipa[13].VX, read_pipa[13].VY, read_pipa[13].VZ);
    glVertex3f(read_pipa[14].VX, read_pipa[14].VY, read_pipa[14].VZ);
    glVertex3f(read_pipa[15].VX, read_pipa[15].VY, read_pipa[15].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[14].VX, read_pipa[14].VY, read_pipa[14].VZ);
    glVertex3f(read_pipa[15].VX, read_pipa[15].VY, read_pipa[15].VZ);
    glVertex3f(read_pipa[16].VX, read_pipa[16].VY, read_pipa[16].VZ);
    glVertex3f(read_pipa[17].VX, read_pipa[17].VY, read_pipa[17].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[16].VX, read_pipa[16].VY, read_pipa[16].VZ);
    glVertex3f(read_pipa[17].VX, read_pipa[17].VY, read_pipa[17].VZ);
    glVertex3f(read_pipa[18].VX, read_pipa[18].VY, read_pipa[18].VZ);
    glVertex3f(read_pipa[19].VX, read_pipa[19].VY, read_pipa[19].VZ);
    glEnd();


    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[18].VX, read_pipa[18].VY, read_pipa[18].VZ);
    glVertex3f(read_pipa[19].VX, read_pipa[19].VY, read_pipa[19].VZ);
    glVertex3f(read_pipa[20].VX, read_pipa[20].VY, read_pipa[20].VZ);
    glVertex3f(read_pipa[21].VX, read_pipa[21].VY, read_pipa[21].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[20].VX, read_pipa[20].VY, read_pipa[20].VZ);
    glVertex3f(read_pipa[21].VX, read_pipa[21].VY, read_pipa[21].VZ);
    glVertex3f(read_pipa[22].VX, read_pipa[22].VY, read_pipa[22].VZ);
    glVertex3f(read_pipa[23].VX, read_pipa[23].VY, read_pipa[23].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[22].VX, read_pipa[22].VY, read_pipa[22].VZ);
    glVertex3f(read_pipa[23].VX, read_pipa[23].VY, read_pipa[23].VZ);
    glVertex3f(read_pipa[0].VX, read_pipa[0].VY, read_pipa[0].VZ);
    glVertex3f(read_pipa[1].VX, read_pipa[1].VY, read_pipa[1].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[0].VX, read_pipa[0].VY, read_pipa[0].VZ);
    glVertex3f(read_pipa[3].VX, read_pipa[3].VY, read_pipa[3].VZ);
    glVertex3f(read_pipa[4].VX, read_pipa[4].VY, read_pipa[4].VZ);
    glVertex3f(read_pipa[7].VX, read_pipa[7].VY, read_pipa[7].VZ);
    glVertex3f(read_pipa[8].VX, read_pipa[8].VY, read_pipa[8].VZ);
    glVertex3f(read_pipa[11].VX, read_pipa[11].VY, read_pipa[11].VZ);
    glVertex3f(read_pipa[12].VX, read_pipa[12].VY, read_pipa[12].VZ);
    glVertex3f(read_pipa[15].VX, read_pipa[15].VY, read_pipa[15].VZ);
    glVertex3f(read_pipa[16].VX, read_pipa[16].VY, read_pipa[16].VZ);
    glVertex3f(read_pipa[19].VX, read_pipa[19].VY, read_pipa[19].VZ);
    glVertex3f(read_pipa[20].VX, read_pipa[20].VY, read_pipa[20].VZ);
    glVertex3f(read_pipa[23].VX, read_pipa[23].VY, read_pipa[23].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[1].VX, read_pipa[1].VY, read_pipa[1].VZ);
    glVertex3f(read_pipa[2].VX, read_pipa[2].VY, read_pipa[2].VZ);
    glVertex3f(read_pipa[5].VX, read_pipa[5].VY, read_pipa[5].VZ);
    glVertex3f(read_pipa[6].VX, read_pipa[6].VY, read_pipa[6].VZ);
    glVertex3f(read_pipa[9].VX, read_pipa[9].VY, read_pipa[9].VZ);
    glVertex3f(read_pipa[10].VX, read_pipa[10].VY, read_pipa[10].VZ);
    glVertex3f(read_pipa[13].VX, read_pipa[13].VY, read_pipa[13].VZ);
    glVertex3f(read_pipa[14].VX, read_pipa[14].VY, read_pipa[14].VZ);
    glVertex3f(read_pipa[17].VX, read_pipa[17].VY, read_pipa[17].VZ);
    glVertex3f(read_pipa[18].VX, read_pipa[18].VY, read_pipa[18].VZ);
    glVertex3f(read_pipa[21].VX, read_pipa[21].VY, read_pipa[21].VZ);
    glVertex3f(read_pipa[22].VX, read_pipa[22].VY, read_pipa[22].VZ);
    glEnd();
}

Selesah sudah pembahasan tentang pipa 3D wire, ini dia kode program secara lengkap, rekan-rekan boleh copy paste, mau cantumin nama author ato tidak itu terserah rekan-rekan, kagak ada paksaan...hehehehe...

//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 <fstream>             

using std::ifstream;

//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;


float Sudut_Putar = 0.0f;
bool cek_error_load;

/////////////////Struct
typedef struct
{
    float VX, VY, VZ;
}Vertex;

Vertex pipa1_vertex[24];
Vertex pipa2_vertex[24];
Vertex pipa3_vertex[24];
Vertex pipa4_vertex[24];

bool Load_All_Data();
void loadPipa(Vertex read_pipa[24], float jari, float tinggi);
void pipa_wire(Vertex read_pipa[24]);

//+++++++++++++++++++++++++++++++++++++++++++
//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;
    }

    ///////////LOAD Vertex
    if (!Load_All_Data())
        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();

        //memakai pandangan 3D perspektif
        gluPerspective(45.0, (GLfloat)lebar_window_Screen / (GLfloat)tinggi_window_Screen, 1.0, 1000.0);

        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

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

        //perhitungan depth buffer diaktifkan
        glEnable(GL_DEPTH_TEST);

        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);
}

bool Load_All_Data()
{
    loadPipa(pipa1_vertex, 0.6f, 0.6f);
    if (cek_error_load == false)
        return false;

    loadPipa(pipa2_vertex, 0.3f, 0.7f);
    if (cek_error_load == false)
        return false;

    loadPipa(pipa3_vertex, 0.1f, 0.8f);
    if (cek_error_load == false)
        return false;

    loadPipa(pipa4_vertex, 0.7f, 0.2f);
    if (cek_error_load == false)
        return false;


    return true;
}

void loadPipa(Vertex read_pipa[24], float jari, float tinggi)
{
    int i = 0;
    double temp_sudut;
    double pi = 3.1415926535;

    ifstream pipaDat;

    cek_error_load = true;

    pipaDat.open("TXT_files/pipa_vertex.txt");

    if (!pipaDat)
    {
        //printf("Error loading pipa_vertex.txt \n");
        cek_error_load = false;
        exit(0);
    }

    while (!pipaDat.eof())
    {
        pipaDat >> read_pipa[i].VX >> read_pipa[i].VY >> read_pipa[i].VZ;
        i++;
    }


    for (i = 0; i < 24; i++)
    {
        temp_sudut = read_pipa[i].VX;
        temp_sudut = (temp_sudut / 180) * pi;
        read_pipa[i].VX = jari * (float)cos(temp_sudut);

        read_pipa[i].VY = read_pipa[i].VY * tinggi;

        temp_sudut = read_pipa[i].VZ;
        temp_sudut = (temp_sudut / 180) * pi;
        read_pipa[i].VZ = jari * (float)sin(temp_sudut);
    }
}

void pipa_wire(Vertex read_pipa[24])
{
    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[0].VX, read_pipa[0].VY, read_pipa[0].VZ);
    glVertex3f(read_pipa[1].VX, read_pipa[1].VY, read_pipa[1].VZ);
    glVertex3f(read_pipa[2].VX, read_pipa[2].VY, read_pipa[2].VZ);
    glVertex3f(read_pipa[3].VX, read_pipa[3].VY, read_pipa[3].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[2].VX, read_pipa[2].VY, read_pipa[2].VZ);
    glVertex3f(read_pipa[3].VX, read_pipa[3].VY, read_pipa[3].VZ);
    glVertex3f(read_pipa[4].VX, read_pipa[4].VY, read_pipa[4].VZ);
    glVertex3f(read_pipa[5].VX, read_pipa[5].VY, read_pipa[5].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[4].VX, read_pipa[4].VY, read_pipa[4].VZ);
    glVertex3f(read_pipa[5].VX, read_pipa[5].VY, read_pipa[5].VZ);
    glVertex3f(read_pipa[6].VX, read_pipa[6].VY, read_pipa[6].VZ);
    glVertex3f(read_pipa[7].VX, read_pipa[7].VY, read_pipa[7].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[6].VX, read_pipa[6].VY, read_pipa[6].VZ);
    glVertex3f(read_pipa[7].VX, read_pipa[7].VY, read_pipa[7].VZ);
    glVertex3f(read_pipa[8].VX, read_pipa[8].VY, read_pipa[8].VZ);
    glVertex3f(read_pipa[9].VX, read_pipa[9].VY, read_pipa[9].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[8].VX, read_pipa[8].VY, read_pipa[8].VZ);
    glVertex3f(read_pipa[9].VX, read_pipa[9].VY, read_pipa[9].VZ);
    glVertex3f(read_pipa[10].VX, read_pipa[10].VY, read_pipa[10].VZ);
    glVertex3f(read_pipa[11].VX, read_pipa[11].VY, read_pipa[11].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[10].VX, read_pipa[10].VY, read_pipa[10].VZ);
    glVertex3f(read_pipa[11].VX, read_pipa[11].VY, read_pipa[11].VZ);
    glVertex3f(read_pipa[12].VX, read_pipa[12].VY, read_pipa[12].VZ);
    glVertex3f(read_pipa[13].VX, read_pipa[13].VY, read_pipa[13].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[12].VX, read_pipa[12].VY, read_pipa[12].VZ);
    glVertex3f(read_pipa[13].VX, read_pipa[13].VY, read_pipa[13].VZ);
    glVertex3f(read_pipa[14].VX, read_pipa[14].VY, read_pipa[14].VZ);
    glVertex3f(read_pipa[15].VX, read_pipa[15].VY, read_pipa[15].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[14].VX, read_pipa[14].VY, read_pipa[14].VZ);
    glVertex3f(read_pipa[15].VX, read_pipa[15].VY, read_pipa[15].VZ);
    glVertex3f(read_pipa[16].VX, read_pipa[16].VY, read_pipa[16].VZ);
    glVertex3f(read_pipa[17].VX, read_pipa[17].VY, read_pipa[17].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[16].VX, read_pipa[16].VY, read_pipa[16].VZ);
    glVertex3f(read_pipa[17].VX, read_pipa[17].VY, read_pipa[17].VZ);
    glVertex3f(read_pipa[18].VX, read_pipa[18].VY, read_pipa[18].VZ);
    glVertex3f(read_pipa[19].VX, read_pipa[19].VY, read_pipa[19].VZ);
    glEnd();


    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[18].VX, read_pipa[18].VY, read_pipa[18].VZ);
    glVertex3f(read_pipa[19].VX, read_pipa[19].VY, read_pipa[19].VZ);
    glVertex3f(read_pipa[20].VX, read_pipa[20].VY, read_pipa[20].VZ);
    glVertex3f(read_pipa[21].VX, read_pipa[21].VY, read_pipa[21].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[20].VX, read_pipa[20].VY, read_pipa[20].VZ);
    glVertex3f(read_pipa[21].VX, read_pipa[21].VY, read_pipa[21].VZ);
    glVertex3f(read_pipa[22].VX, read_pipa[22].VY, read_pipa[22].VZ);
    glVertex3f(read_pipa[23].VX, read_pipa[23].VY, read_pipa[23].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[22].VX, read_pipa[22].VY, read_pipa[22].VZ);
    glVertex3f(read_pipa[23].VX, read_pipa[23].VY, read_pipa[23].VZ);
    glVertex3f(read_pipa[0].VX, read_pipa[0].VY, read_pipa[0].VZ);
    glVertex3f(read_pipa[1].VX, read_pipa[1].VY, read_pipa[1].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[0].VX, read_pipa[0].VY, read_pipa[0].VZ);
    glVertex3f(read_pipa[3].VX, read_pipa[3].VY, read_pipa[3].VZ);
    glVertex3f(read_pipa[4].VX, read_pipa[4].VY, read_pipa[4].VZ);
    glVertex3f(read_pipa[7].VX, read_pipa[7].VY, read_pipa[7].VZ);
    glVertex3f(read_pipa[8].VX, read_pipa[8].VY, read_pipa[8].VZ);
    glVertex3f(read_pipa[11].VX, read_pipa[11].VY, read_pipa[11].VZ);
    glVertex3f(read_pipa[12].VX, read_pipa[12].VY, read_pipa[12].VZ);
    glVertex3f(read_pipa[15].VX, read_pipa[15].VY, read_pipa[15].VZ);
    glVertex3f(read_pipa[16].VX, read_pipa[16].VY, read_pipa[16].VZ);
    glVertex3f(read_pipa[19].VX, read_pipa[19].VY, read_pipa[19].VZ);
    glVertex3f(read_pipa[20].VX, read_pipa[20].VY, read_pipa[20].VZ);
    glVertex3f(read_pipa[23].VX, read_pipa[23].VY, read_pipa[23].VZ);
    glEnd();

    glBegin(GL_LINE_LOOP);
    glVertex3f(read_pipa[1].VX, read_pipa[1].VY, read_pipa[1].VZ);
    glVertex3f(read_pipa[2].VX, read_pipa[2].VY, read_pipa[2].VZ);
    glVertex3f(read_pipa[5].VX, read_pipa[5].VY, read_pipa[5].VZ);
    glVertex3f(read_pipa[6].VX, read_pipa[6].VY, read_pipa[6].VZ);
    glVertex3f(read_pipa[9].VX, read_pipa[9].VY, read_pipa[9].VZ);
    glVertex3f(read_pipa[10].VX, read_pipa[10].VY, read_pipa[10].VZ);
    glVertex3f(read_pipa[13].VX, read_pipa[13].VY, read_pipa[13].VZ);
    glVertex3f(read_pipa[14].VX, read_pipa[14].VY, read_pipa[14].VZ);
    glVertex3f(read_pipa[17].VX, read_pipa[17].VY, read_pipa[17].VZ);
    glVertex3f(read_pipa[18].VX, read_pipa[18].VY, read_pipa[18].VZ);
    glVertex3f(read_pipa[21].VX, read_pipa[21].VY, read_pipa[21].VZ);
    glVertex3f(read_pipa[22].VX, read_pipa[22].VY, read_pipa[22].VZ);
    glEnd();
}

//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
    //...........................
    //mundurkan objek sebanyak 5 satuan
    //ke arah sumbu -Z
    glTranslatef(0.0f, 0.0f, -5.0f);
    glRotatef(15.0, 1.0f, 0.0f, 1.0f);
    glRotatef(Sudut_Putar, 0.0f, 1.0f, 0.0f);

    Sudut_Putar += 0.01f;
    if (Sudut_Putar > 360.0f)
        Sudut_Putar = 0.0f;


    ///////////Object di sini

    //glRotatef(Sudut_Putar, 0.0f, 1.0f, 0.0f);

    //sumbu x
    glBegin(GL_LINES);
    glVertex3f(3.0f, 0.0f, 0.0f);
    glVertex3f(-3.0f, 0.0f, 0.0f);
    glEnd();
    //sumbu y
    glBegin(GL_LINES);
    glVertex3f(0.0f, 3.0f, 0.0f);
    glVertex3f(0.0f, -3.0f, 0.0f);
    glEnd();
    //sumbu z
    glBegin(GL_LINES);
    glVertex3f(0.0f, 0.0f, 3.0f);
    glVertex3f(0.0f, 0.0f, -3.0f);
    glEnd();

    //display pipa
    glTranslatef(-1.0f, 0.0f, -1.0f);
    pipa_wire(pipa1_vertex);
    glTranslatef(2.0f, 0.0f, 0.0f);
    pipa_wire(pipa2_vertex);
    glTranslatef(0.0f, 0.0f, 2.0f);
    pipa_wire(pipa4_vertex);
    glTranslatef(-2.0f, 0.0f, 0.0f);
    pipa_wire(pipa3_vertex);

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

Salam Hangat


Heriady
heriady.yoh@gmail.com


Download program disini nih silahkan ya...


Sumber
Artikel ini bersumber dari buku Pemrograman Grafik 3D menggunakan C & OpenGL, karangan Heriady (halaman 88 s/d 98)












Artikel terkait
Program balok 3D wire
Program balok 3D solid
Program Tangki Air 3D
Program Meja 3D