Friday, 24 September 2010

Efek Transparan pada Gambar

Gambar 1. Penampakan Code::Blocks, hihihihi...


Andi:"Sial kepalaku kejedot kaca, habis bening banget sih jadinya nggak kelihatan."
Budi:"Oh itu berarti nilai Alpha pada kaca adalah 0."
Andi:"Hah, apaan?"


Seperti cuplikan perbincangan 2 orang diatas, nilai Alpha pada suatu gambar (image) akan mengatur nilai transparannya. Sehingga objek yang berada dibelakangnya dapat terlihat dengan (sangat) jelas jika nilai Alphanya rendah. Semakin rendah nilai alpha maka semakin transparan dan bahkan tidak kelihatan sama sekali, begitu pula sebaliknya. Berikut link download filenya (source code dan program jadi) dan yang dibawahnya contoh kodenya:

Link : http://www.mediafire.com/?17j66h6z2b3igij
Size : 144 KB
Code :

/*/
*****  *****  *****  *****  *****

---------------------------------
    Efek Transparan pada Gambar
---------------------------------
You can modified, and distribute this
source code, but please don't remove this link:

http://membuatgamedengancpp.blogspot.com/

Thank you for your attention.
---------------------------------

- krofz
*****  *****  *****  *****  *****
/*/
#ifdef __cplusplus
    #include <cstdlib>
#else
    #include <stdlib.h>
#endif
#ifdef __APPLE__
#include <SDL/SDL.h>
#else
#include <SDL.h>
#endif

int main ( int argc, char** argv )
{
    // initialize SDL video
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        return 1;
    }

    // make sure SDL cleans up before exit
    atexit(SDL_Quit);

    // create a new window
    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16,
                                           SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !screen )
    {
        printf("Unable to set 640x480 video: %s\n", SDL_GetError());
        return 1;
    }
    SDL_WM_SetCaption("Efek Transparan pada Gambar",NULL);

    // load an image
    SDL_Surface* bmp = SDL_LoadBMP("cb.bmp");
    if (!bmp)
    {
        printf("Unable to load bitmap: %s\n", SDL_GetError());
        return 1;
    }

    // centre the bitmap on screen
    SDL_Rect dstrect;
    dstrect.x = (screen->w - bmp->w) / 2;
    dstrect.y = (screen->h - bmp->h) / 2;

    // program main loop
    bool done = false;

    int alpha = 1, fps = 0;    // program main loop
    const int frame_perdetik = 20;
    while (!done)
    {
        fps = SDL_GetTicks();

        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                done = true;
                break;

                // check for keypresses
            case SDL_KEYDOWN:
                {
                    // exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                }
            } // end switch
        } // end of message processing

        // DRAWING STARTS HERE

        // clear screen
        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));

        alpha++;
        SDL_SetAlpha( bmp, SDL_SRCALPHA, 100+(alpha%150));

        // draw bitmap
        SDL_BlitSurface(bmp, 0, screen, &dstrect);

        // DRAWING ENDS HERE

        // finally, update the screen :)
        SDL_Flip(screen);

        int getDetik = SDL_GetTicks() - fps;
        if( getDetik < (1000/frame_perdetik)){
            SDL_Delay((1000/frame_perdetik) - getDetik);
        }
    } // end main loop

    // free loaded bitmap
    SDL_FreeSurface(bmp);

    // all is well ;)
    printf("Exited cleanly\n");
    return 0;
}

// ******************************* //
//      Source Code by Krofz       //
// ******************************* //

Kode diatas akan mengatur nilai alpha surface bmp, sehingga tampak seperti animasi munculnya gambar logo Code::Blocks dari kegelapan. Karena transparan sehingga warna pixel pada gambar akan tercampur dengan warna pixel gambar dibelakangnya, dalam hal ini adalah warna hitam pada layar (screen). Yah kurang lebih seperti itulah. Fungsi untuk mengatur nilai alpha ini, namanya sangat jelas dan mudah diingat, yaitu "SDL_SetAlpha(SDL_Surface *surface, Uint32 flag, Uint8 alpha)". Argumen pertama diisi dengan variabel surface berpointer (SDL_Surface *). Argumen kedua adalah flag atau method yang akan digunakan, dan terakhir nilai Alpha. Salah satu contoh yang sangat mudah untuk menpraktekkan nilai alpha adalah pada bayangan seperti gambar berikut:

Gambar 2. (a) Tanpa mengatur nilai Alpha atau nilai Alphanya tinggi (>250), dan (b) dengan mengatur nilai Alpha rendah.

Bisa dilihat pada gambar diatas, ada bayangan tapi nggak ada orangnya? ih.. serem (Zzz.. ngaco). Perlu diketahui bahwa untuk memproses atau men-setting nilai Alpha memerlukan resource yang cukup besar. Ini dikarenakan program SDL dalam mengolah dan menampilkan nilai Alpha memanfaatkan kerja Processor, dan bukan perangkat keras seperti Graphic Card. Jika program (game) kita sudah semakin kompleks dengan banyaknya proses transparansi dan penggambaran, sepertinya sudah saatnya beralih ke OpenGL (atau SDL + OpenGL). Tapi untuk saat ini program yang kita buat masih sangat sederhana, ditambah lagi dengan spesifikasi komputer umum saat ini yang sudah sangat canggih. Sepertinya belum saatnya.

- krofz

Wednesday, 15 September 2010

Segitiga dari Kotak (3)

Tulisan ini merupakan lanjutan dari:
Segitiga dari Kotak (1)
Segitiga dari Kotak (2)


Bagaikan air yang mengalir dari atas ke bawah.


Sekarang kita lanjutkan kebagian bagaimana program ini bekerja atau alur dari program. Kita langsung masuk ke loop (pengulangan) while atau loop utama program kita. Pertama adalah memperoleh detik awal pengulangan yang berfungsi untuk mengatur FPS (Frame Per Second) yang akan diproses selanjutnya pada akhir statement loop. Kedua adalah proses kontrol program dengan SDL_PollEvent(). Kita hanya membuat sebuah kondisi jika tombol panah kiri atau kanan ditekan, maka akan mengatur nilai dari variabel jumlahKotak. Kondisinya membatasi var jumlahKotak dengan jumlah minimal 3 dan maksimal 25. Dan tombol Escape untuk keluar atau menutup program.

Selanjutnya proses pengambaran pada fungsi SegitigaDariKotak() sesudah memberi alas pada layar (screen) dengan warna biru muda dengan SDL_FillRect(). Untuk argumen kedua fungsi, jumlah kotaknya disesuaikan dengan var jumlahKotak. Sebetulnya lebih tepat dibilang jumlah baris berbentuk kotak pada segitiga dibanding jumlah kotak yang lebih mengarah pada banyaknya kotak yang tampil, benar nggak? - sebodoh ah (pengacau bahasa). Dunia pemrograman memang penuh dengan singkatan, hehehe . Pada fungsi SegitigaDariKotak(), variabel Size akan mempermudahkan kita dalam mengatur tata letak, ukuran kotak dan segala perhitungannya. Variabel global red, green, dan blue berfungsi untuk mengatur warna yang tampil pada kotak agar lebih variatif.

Bagian utama dalam program ini adalah pengulangan for didalam fungsi SegitigaDariKotak() ini. Kita mulai dari koordinat x dan y. Meletakkannya secara manual selain membuat kode program menjadi panjang dan belum tentu rata/rapi. Belum lagi bagaimana caranya apakah menggunakan kondisi if? (jadi bingung sendiri ). So, perhatikan kode utama program kita:


...
    for(int c=1;c<=jumlah;c++)
    {
        int _X = (lebar_layar/2 - c*Size/2);
        int _Y = (tinggi_layar/2 - jumlah*Size/2)+ (c-1)*Size;

        //_blok = membuat blok hitam
        SDL_Rect _blok = {_X,_Y,c*Size,Size};
        SDL_FillRect(screen,&_blok,SDL_MapRGB(screen->format,0,0,0));

        for(int d=0;d<c;d++)
        {
            SDL_Rect _kotak = {_X+(d*Size)+2,_Y+2,Size-4,Size-4};
            SDL_FillRect(screen,&_kotak,SDL_MapRGB(screen->format,
                (c*3+red)%255,green%255,blue%255));
        }
    }
...

Sebelum melanjutkan, jika anda kurang jelas dengan SDL_Rect silahkan membaca kembali postingan sebelumnya. Sudah? Ok kita lanjutkan, dengan membuat variabel _X dan _Y agar nilainya dapat diterapkan pada kotak (SDL_Rect) _blok dan _kotak. Ini untuk menghindari perhitungan koordinat sebanyak 2 kali. Jika jumlah sama dengan 5, maka nilai _X didapat dari perhitungan lebar_layar (dalam program ini 640) dibagi 2 atau setengahnya lebar_layar dikurang c*Size/2 (misal Size = 35 hasil dari 40 - 5, dan berada pada pengulangan kedua - c = 2), sehingga _X = 640/2 - 2*35/2 = 320 - 35 = 285. Jika c diawali dengan 0 (int c=0, c < jumlah) maka untuk memperoleh nilai _X adalah seperti berikut _X = (lebar_layar/2 - (c+1)*Size/2), tetapi akan ada beberapa perubahan kode disana-sini. Sedangkan y diperoleh dari setengah tinggi_layar (dalam program ini 480) dikurang jumlah*Size/2 setelah itu ditambah (c-1)*Size, sehingga nilai _Y pada pengulangan kedua adalah _Y = (480/2 - 5*35/2) + (2-1)*35 = (240 - 87) + 35 = 153 + 35 = 188. So, untuk blok (yang warnain hitam) pada pengulangan ke-2 dengan jumlahKotak = 5 memiliki koordinat (285,188). Jika digambarkan akan seperti berikut:

Gambar 1. Mari kita letakkan yang rapi.

Dimana c1a = c1b, dan c2a = c2b. Itu untuk koordinatnya sedangkan untuk pengambarannya dibagi menjadi 2 bagian, yaitu blok dan kotak. Dimana blok untuk membuat seakan-akan ada garis tepi pada kotak, dan kotak adalah bentuk aslinya. Blok kita beri warna hitam (RGB = 0,0,0), dan untuk kotak kita buat sesuai nilai dari variabel red, green, dan blue. Koordinat kotak kita beri sedikit jarak 2 px (px = pixel, baik x maupun y) serta lebar dan tingginya dikurangi 4 px. Supaya saat pengambaran lebih menyatu dengan si blok dan bentuknya jelas, tidak seperti berikut:

Gambar 2. (a) Tanpa menggunakan blok dan (b) dengan blok, hanya saja kotak menambah 2 px untuk x dan y tetapi lebar dan tingginya tidak dikurangi 4 px.

Dengan ini diharapkan sudah mengerti alur dari program yang kita buat ini sehingga kita dapat membuat program sejenis yang lebih hebat lagi. So, happy coding.

- krofz

Tuesday, 7 September 2010

Segitiga dari Kotak (2)

Tulisan ini merupakan lanjutan dari:
Segitiga dari Kotak (1)

Ada sesuatu yang menarik dari program SDL yang satu ini, yaitu kehadiran pustaka (library) "windows.h". Untuk apa pustaka ini? Tentunya untuk membuat program - program pada Sistem Operasi (SO) Windows atau yang biasa disebut "Win32 Application". Kehadirannya disini berfungsi untuk memanggil fungsi "MessageBox()", sebuah fungsi yang akan menciptakan "Kotak" yang berisi "Pesan", seperti gambar berikut:

Argumen kedua berfungsi menampilkan teks dalam kotak, argumen ketiga merupakan caption/judul pada kotak. Dan argumen keempat untuk memberikan tanda (flag) apa saja yang akan tampil di Kotak Pesan kita. Tentu tanda yang diberikan terbatas. Lalu argumen pertama untuk apa? saat ini belum bisa berkomentar banyak . Sehingga fungsi ini mempermudahkan kita dalam menyampaikan pesan tentang penggunaan program (SDL) atau kontrol program buatan kita. Karena program yang dibuat masih sederhana dan hanya menggunakan panah kiri dan kanan sebagai kontrolnya. Tentu cara ini lebih cepat dibanding membuat sebuah surface dari font dengan memanggil SDL_ttf dan segala bentuk inisialisasi dasarnya (TTF_Init(), TTF_Font, dll). Atau menampilkan gambar sebagai informasi penggunaan atau kontrol program, yang semuanya ini tidak 'murah' perlu SDL_image untuk pemanggilan gambar bertipe (.jpg, .png, dsb).

Tetapi karena pustaka ini untuk SO Windows, jadi kemungkinan besar tidak berjalan (dengan mulus) di SO lainnya misal Linux. Sehingga cara yang tidak 'murah' tersebut lebih memuaskan daripada cara 'instan'. Itulah mengapa makanan instan (Fast Food, umumnya juga disebut Junk Food) itu tidak disarankan, lho? . Tapi jika anda masih tetap ngotot ingin menampilkan informasi penggunaan program tanpa pustaka windows dan SDL_ttf atau SDL_image, dapat menggunakan file gambar berformat bitmap (.bmp). Karena file bitmap merupakan format dasar gambar yang tidak terkompresi, sehingga penggunaan SDL.h -pun sudah dapat menampilkannya, berikut contoh potongan kodenya (Aku ambil dari template Code::Blocks):


...
    // load an image
    SDL_Surface* bmp = SDL_LoadBMP("infoProgram.bmp");
    if (!bmp)
    {
        printf("Unable to load bitmap: %s\n", SDL_GetError());
        return 1;
    }
    
    // centre the bitmap on screen
    SDL_Rect dstrect;
    dstrect.x = (screen->w - bmp->w) / 2;
    dstrect.y = (screen->h - bmp->h) / 2;
 ...
     // draw bitmap
        SDL_BlitSurface(bmp, 0, screen, &dstrect);
...

Tinggal menganti argumen pada SDL_LoadBMP() dengan nama file yang akan ditunjuk. Lalu menampilkannya dengan SDL_BlitSurface() .

- krofz
 

back to top

back to top