Sabtu, 14 September 2013

Perjuangan TA Grafika Komputer

   Ini tugas akhir grafikaku sama rekanku, salah satu anak PTI D 2011 di UM, Bayu Dian Anggara. Sebut aja Bayu. Dia yang merancang semua gambar flashdisknya. Banyak kekecewaan dari pembuatan ni objek karena keterbatasan vertex nya. Pengennya si Bayu ini sesuai dengan aslinya, dan ternyata kalau sesuai aslinya tidak bisa di load karena kebanyakan vertex. Jadi, jangan banyak-banyak vertex deh supaya bisa ke load. 
Di atas bicara teman, nah, kerjaanku apa dong? Aku hanya editing animasinya aja, itupun masih nyontek latihan-latihan kemarennya.Kolaborasi yang sangat bagus, sehingga menghasilkan sebuah tugas akhir yang lumayan membanggakan diri sendiri. Dan akhirnya dapat kesempatan ujian pertama deh(perjuangan). 

Ini nih sedikit bocoran tentang codingnya ~ ~
#include <windows.h>
#include <iostream>
#include <STRING.H>
#include <index.h>
#include <3dsloader.h>
#include <assert.h>
#include <fstream>
#include <stdlib.h>
#include <gl/glut.h>
#include <imageloader.h>

int w=480, h=480;  //ukuran window
float a = 1, b = 1;  //untuk translasi
int sx,sy,sz=0;     //untuk rotate
float sudut=0,size=1,p=0,q=0; //size untuk scale dan sudut untuk rotate, p dan q lighting

//int filling=1; //0=OFF 1=ON
obj_type object;

void gambar()
{
    int l_index;

    glBegin(GL_TRIANGLES); 
    for (l_index=0;l_index<object.polygons_qty;l_index++)
{
        //----------------- FIRST VERTEX -----------------
        // Texture coordinates of the first vertex
        glTexCoord2f( object.mapcoord[ object.polygon[l_index].a ].u,
                      object.mapcoord[ object.polygon[l_index].a ].v);
        // Coordinates of the first vertex
        glVertex3f( object.vertex[ object.polygon[l_index].a ].x,
                    object.vertex[ object.polygon[l_index].a ].y,
                    object.vertex[ object.polygon[l_index].a ].z); //Vertex definition

        //----------------- SECOND VERTEX -----------------
        // Texture coordinates of the second vertex
        glTexCoord2f( object.mapcoord[ object.polygon[l_index].b ].u,
                      object.mapcoord[ object.polygon[l_index].b ].v);
        // Coordinates of the second vertex
        glVertex3f( object.vertex[ object.polygon[l_index].b ].x,
                    object.vertex[ object.polygon[l_index].b ].y,
                    object.vertex[ object.polygon[l_index].b ].z);
        
        //----------------- THIRD VERTEX -----------------
        // Texture coordinates of the third vertex
        glTexCoord2f( object.mapcoord[ object.polygon[l_index].c ].u,
                      object.mapcoord[ object.polygon[l_index].c ].v);
        // Coordinates of the Third vertex
        glVertex3f( object.vertex[ object.polygon[l_index].c ].x,
                    object.vertex[ object.polygon[l_index].c ].y,
                    object.vertex[ object.polygon[l_index].c ].z);
    }
    glEnd();
}

GLuint loadTexture(Image* image)
{
GLuint textureId;    
glGenTextures(1, &textureId);   //ruang untuk texture
glBindTexture(GL_TEXTURE_2D, textureId);  
glTexImage2D(GL_TEXTURE_2D,       // GL texture
0,  // awalnya 0
GL_RGB,  // Format OpenGL untuk gambar
image->width, image->height, // panjang dan lebar gambar
0, // border gambar
GL_RGB, // Format pixel RGB
GL_UNSIGNED_BYTE, // tidak menggunakan angka

image->pixels); // data pixel
return textureId; // mengulangi id texture
}

//imageloader
using namespace std;

Image::Image(char* ps, int w, int h) : pixels(ps), width(w), height(h) {}

Image::~Image() 
{
delete[] pixels;
}

namespace 
{
int toInt(const char* bytes) 
{
return (int)(((unsigned char)bytes[3] << 24) |
((unsigned char)bytes[2] << 16) |
((unsigned char)bytes[1] << 8) |
(unsigned char)bytes[0]);
}

short toShort(const char* bytes) 
{
return (short)(((unsigned char)bytes[1] << 8) |
  (unsigned char)bytes[0]);
}

int readInt(ifstream &input) 
{
char buffer[4];
input.read(buffer, 4);
return toInt(buffer);
}

short readShort(ifstream &input) 
{
char buffer[2];
input.read(buffer, 2);
return toShort(buffer);
}

template<class T>
class auto_array 
{
private:
T* array;
mutable bool isReleased;
public:
explicit auto_array(T* array_ = NULL) :
array(array_), isReleased(false) 
{
}

auto_array(const auto_array<T>&aarray) 
{
array = aarray.array;
isReleased = aarray.isReleased;
aarray.isReleased = true;
}

~auto_array() 
{
if (!isReleased &&array != NULL) 
{
delete[] array;
}
}

T* get() const 
{
return array;
}

T &operator*() const 
{
return *array;
}

void operator=(const auto_array<T>&aarray) 
{
if (!isReleased &&array != NULL) 
{
delete[] array;
}
array = aarray.array;
isReleased = aarray.isReleased;
aarray.isReleased = true;
}

T* operator->() const 
{
return array;
}

T* release() 
{
isReleased = true;
return array;
}

void reset(T* array_ = NULL) 
{
if (!isReleased &&array != NULL) 
{
delete[] array;
}
array = array_;
}

T* operator+(int i) 
{
return array + i;
}

T &operator[](int i) 
{
return array[i];
}
};
}

Image* loadBMP(const char* filename) 
{
ifstream input;
input.open(filename, ifstream::binary);
assert(!input.fail() || !"Could not find file");
char buffer[2];
input.read(buffer, 2);
assert(buffer[0] == 'B' && buffer[1] == 'M' || !"Not a bitmap file");
input.ignore(8);
int dataOffset = readInt(input);

//Read the header
int headerSize = readInt(input);
int width;
int height;
switch(headerSize) 
{
case 40:
//V3
width = readInt(input);
height = readInt(input);
input.ignore(2);
assert(readShort(input) == 24 || !"Image is not 24 bits per pixel");
assert(readShort(input) == 0 || !"Image is compressed");
break;
case 12:
//OS/2 V1
width = readInt(input);
height = readInt(input);
input.ignore(2);
assert(readShort(input) == 24 || !"Image is not 24 bits per pixel");
break;
case 64:
//OS/2 V2
assert(!"Can't load OS/2 V2 bitmaps");
break;
case 108:
//Windows V4
assert(!"Can't load Windows V4 bitmaps");
break;
case 124:
//Windows V5
assert(!"Can't load Windows V5 bitmaps");
break;
default:
assert(!"Unknown bitmap format");
}

//Read the data
int bytesPerRow = ((width * 3 + 3) / 4) * 4 - (width * 3 % 4);
int size = bytesPerRow * height;
auto_array<char> pixels(new char[size]);
input.seekg(dataOffset, ios_base::beg);
input.read(pixels.get(), size);

//Get the data into the right format
auto_array<char> pixels2(new char[width * height * 3]);
for(int y = 0; y < height; y++) 
{
for(int x = 0; x < width; x++) 
{
for(int c = 0; c < 3; c++) 
{
pixels2[3 * (width * y + x) + c] =
pixels[bytesPerRow * y + 3 * x + (2 - c)];
}
}
}

input.close();
return new Image(pixels2.release(), width, height);
}

void resize(int w1, int h1)
{
glViewport(0,0,w1,h1);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0, (float) w1/(float) h1, 1.0,300.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

void reshape (int w, int h)
{
glViewport(0,0,(GLsizei)w,(GLsizei)h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective (60,(GLfloat)w/(GLfloat)h, 1, 100);
glMatrixMode(GL_MODELVIEW);
}

void light()
{
GLfloat LightPosition[] = {10.0f, 10.0f, 20.0f, 0.0f};
GLfloat LightAmbient[] = {0.0f, 1.0f, 0.0f, 1.0f};
GLfloat LightDiffuse[] = {0.7f, 0.7f, 0.7f, 1.0f};
GLfloat LightSpecular[] = {0.5f, 0.5f, 0.5f, 1.0f};
GLfloat Shine[] = { 80 };

glShadeModel(GL_SMOOTH);
glClearColor(0.0f,0.0f,0.0f,0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);

//glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);
//glMaterialfv(GL_FRONT, GL_AMBIENT, LightAmbient);
 glMaterialfv(GL_FRONT, GL_SPECULAR, LightSpecular);
 glMaterialfv(GL_FRONT, GL_SHININESS, Shine);

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
return;
}

void init()
{
/*glShadeModel(GL_SMOOTH);
glClearColor(0.0f,0.0f,0.0f,0.5f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);*/

Load3DS (&object,"gambar/fd.3ds");
Image* image = loadBMP("gambar/map.bmp");
object.id_texture = loadTexture(image);
return;
}

void mydisplay()
{
light();    //memanggil fungsi lighting
glLoadIdentity();

GLfloat LightPosition[] = {10.0f, 10.0f, 50.0f, 0.0f};
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
LightPosition[0] = p;
LightPosition[1] = q;
glLightfv(GL_LIGHT0, GL_POSITION, LightPosition);

//glMatrixMode(GL_MODELVIEW);
glEnable(GL_COLOR_MATERIAL);

glEnable(GL_TEXTURE_2D); //mengaktifkan fungsi texture
glBindTexture(GL_TEXTURE_2D, object.id_texture); 
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
//tampilan pertama kali objek
glTranslatef(0 , 0, -25); //translate objek pertama
glScalef(0.8,0.8,0.8); //memperkecil objek pertama kali tampil

glPushMatrix();
//glEnable(GL_COLOR_MATERIAL);
glScalef(size,size,size);
glTranslatef(a, b, 0);
glRotatef(sudut,sx,sy,sz);

gambar();

glDisable(GL_TEXTURE);   //menonaktifkan fungsi texture
glutSwapBuffers();
}

//interaksi keyboard dengan keyboard normal
void myKeyboard(unsigned char key, int x, int y)
{
if(key=='x')
{
sudut+=10;
sx=1;
sy=0;
sz=0;
}
else if (key=='y')
{
sudut+=10;
sx=0;
sy=1;
sz=0;
}
else if (key=='z')
{
sudut+=10;
sx=0;
sy=0;
sz=1;
}
}


//interaksi mouse
void mouse (int button, int state, int xmouse, int ymouse)
{
if(button == GLUT_LEFT_BUTTON && state==GLUT_DOWN)
{
p=(xmouse-(w/2));
q=((h/2) - ymouse);
}
else if (button == GLUT_RIGHT_BUTTON && state==GLUT_DOWN)
{
size+=1;
}
else if(button == GLUT_MIDDLE_BUTTON && state==GLUT_DOWN)
{
size--;
}
}

void motion(int x, int y)
{
p=x - (w/2);
q=(h/2) - y;
}

//interaksi keyboard dengan spesialkeyboard
void mySpecialKeyboard(int key, int x, int y)
{
switch(key)
{
case GLUT_KEY_DOWN:
b-=0.5;
break;
case GLUT_KEY_UP:
b+=0.5;
break;
case GLUT_KEY_LEFT:
a-=0.5;
break;
case GLUT_KEY_RIGHT:
a+=0.5;
break;
}
}


//fungsi timer
void timer(int value)
{
//animasi gambar
if (sudut <= 710)
{
sudut+=10;  
sx=sy=sz=1;
}
glutPostRedisplay();
glutTimerFunc(250,timer,0);

}

//fungsi main
void main(int argc, char **argv)
{

glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH | GLUT_RGBA);
glutInitWindowPosition(100,100);
glutInitWindowSize(w, h);
glutCreateWindow("Flashdisk Kelompok 5");
gluOrtho2D(-w/2, w/2 ,-h/2 ,h/2);
glutDisplayFunc(mydisplay);
glutReshapeFunc(resize);
init();
glutMotionFunc(motion);
glutTimerFunc(50,timer,0);
glutKeyboardFunc(myKeyboard);
glutSpecialFunc(mySpecialKeyboard);
glutMouseFunc(mouse);
glClearColor(1,1,1,1);
glutMainLoop();

}




Ditambah loadernya sendiri ya teman-teman. kan hanya sedikit bocoran. Semoga bisa bermanfaat sebagai referensi tugas-tugas grafika kalian. Semoga bisa membantu kalian. :)


Semangat~ ~ ~ 

Tidak ada komentar: