Membuat Segitiga dalam Segitiga 3 Dimensi (Sierpinski Gasket) dengan Inputan Mouse dan Keyboard
Cerita begini, dosen kuliah komputer grafik memberi tugas kedua dengan ketentuan membuat gambar 3 dimensi (3D) dengan betuk segitiga dalam segitiga atau bahasa kerennya Sierpinski Gasket. Program ini juga harus bisa menerima inputan dan berinteraksi dengan user dengan menggunakan OpenGL, terserah bahasa program apa saja. kebetulan di komputer saya telah terinstal Dev C++, nah tinggal nambahi library OpenGL dech. untuk cara menginstal OpenGL di Dev C++, silakan ikuti Tutorial Instalasi OpenGL di Dev C++ .
nah, kalo di Dev C++ sudah terinstal OpenGL silakan mencoba tutorial berikut.
- Klik File --> New --> Project
- Tuliskan nama project lalu pilih Empty Project setelah itu Save project Anda
- Klik Kanan pada project Anda lalu pilih New File.
- Nah, Saatnya koding. masukkan kode berikut ini:
//includes #include <iostream> #include <math.h> #include <gl/glut.h> //NOTE: This file may be included in the system. //functions void ReshapeGlutWindow(int _width, int _height); void IdleGlutFunction(); void KeyboardGlutFunction(unsigned char _key, int _x, int _y); void KeyboardUpGlutFunction(unsigned char _key, int _x, int _y); void MouseButtonGlutFunction(int _button, int _state, int _x, int _y); void MouseMotionGlutFunction(int _x, int _y); void DisplayGlutWindow(); void SierpinskiGasket3f(float _rad, int _count); void SierpinskiGasket3f_A(float _point0Arr[], float _point1Arr[], float _point2Arr[], float _point3Arr[], int _count); void SierpinskiGasket3f_LineMidPoint(float _midPointOut[], float _point0Arr[], float _point1Arr[]); //camera position and rotation float camPos[3] = {0.0f, 0.0f, 370.0f}; //x,y,z position float camRot[3] = {0.0f, 0.0f, 0.0f}; //x,y,z rotation float camPosKeyDown[3] = {0, 0, 0}; //strafe-left-right, move-forward-backward, rise-down-up bool camRotMouseMoveEnable = false; int camRotMouseCord[2] = {0, 0}; //rotate-horozontal, rotate-verical int main(int argc, char **argv) { //initialize GLUT glutInit(&argc, argv); //position of the viewport glutInitWindowPosition(10, 10); //size of viewable window glutInitWindowSize(800, 600); //what type of display to show // GLUT_DEPTH - enable depth buffer // GLUT_DOUBLE - set tp double buffering // GLUT_RGBA - set red, green, blue, and alpha color mode glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA); //create window with specified titile glutCreateWindow("Andi Sholihin - 09.04.111.00011 --> Sierpinski Gasket dgn Input Mouse dan Keyboard"); //reshaping function glutReshapeFunc(ReshapeGlutWindow); //idle function glutIdleFunc(IdleGlutFunction); //keyboard key-down function glutKeyboardFunc(KeyboardGlutFunction); //keyboard key-up function glutKeyboardUpFunc(KeyboardUpGlutFunction); //mouse-click function glutMouseFunc(MouseButtonGlutFunction); //mouse-clicked-move funtion glutMotionFunc(MouseMotionGlutFunction); //display function glutDisplayFunc(DisplayGlutWindow); //begin loop glutMainLoop(); //end with success return 0; } void ReshapeGlutWindow(int _width, int _height) { //fix width if(_width < 1) { _width = 1; } //fix height if(_height < 1) { _height = 1; } //determine the aspect ratio of viewport float ratio = ((float)_width)/((float)_height); //set our current working matrix to the projection matrix stack glMatrixMode(GL_PROJECTION); //replace the current matrix with the identity matrix glLoadIdentity(); //set our viewport glViewport(0, 0, _width, _height); //set up our perspective projection matrix // 45 - field of view degrees in y // ratio - field of view degrees in x // 0 - distance of viewer to near clipping plane // 1000 - distance of viewer to far clipping plane gluPerspective(45, ratio, 0, 1000); //set our current working matrix to the view matrix stack glMatrixMode(GL_MODELVIEW); //enable depth (i.e. z-buffer) glEnable(GL_DEPTH_TEST); //replace the current matrix with the identity matrix glLoadIdentity(); } void IdleGlutFunction() { glutPostRedisplay(); } void KeyboardGlutFunction(unsigned char _key, int _x, int _y) { switch(_key) { case 'a': //strafe-left camPosKeyDown[0] = -1.0f; break; case 'd': //strafe-right camPosKeyDown[0] = 1.0f; break; case 's': //move-down camPosKeyDown[1] = -1.0f; break; case 'w': //move-up camPosKeyDown[1] = 1.0f; break; case 'c': //rise-down camPosKeyDown[2] = -1.0f; break; case ' ': //rise-up camPosKeyDown[2] = 1.0f; break; } } void KeyboardUpGlutFunction(unsigned char _key, int _x, int _y) { switch(_key) { case 'a': //left camPosKeyDown[0] = 0.0f; break; case 'd': //right camPosKeyDown[0] = 0.0f; break; case 's': //down camPosKeyDown[1] = 0.0f; break; case 'w': //up camPosKeyDown[1] = 0.0f; break; case 'c': //lower camPosKeyDown[2] = 0.0f; break; case ' ': //rise camPosKeyDown[2] = 0.0f; break; } } void MouseButtonGlutFunction(int _button, int _state, int _x, int _y) { if(_button == 0) { if(_state == 0) { camRotMouseMoveEnable = true; camRotMouseCord[0] = _x; camRotMouseCord[1] = _y; } else if(_state == 1) { camRotMouseMoveEnable = false; } } } void MouseMotionGlutFunction(int _x, int _y) { if(camRotMouseMoveEnable) { camRot[0] += (((float)(camRotMouseCord[1] - _y)) / 10); camRotMouseCord[1] = _y; camRot[2] += (((float)(camRotMouseCord[0] - _x)) / 10); camRotMouseCord[0] = _x; } } void DisplayGlutWindow() { //update camera position //NOTE: camera rotation is already updated float zRowRad = camRot[2]*(3.141592653589793238462643f/180.0f); camPos[0] += 0.5f*camPosKeyDown[0]*cosf(zRowRad); //strafe-left-right on x camPos[1] += 0.5f*camPosKeyDown[0]*sinf(zRowRad); //strafe-left-right on y camPos[0] -= 0.5f*camPosKeyDown[1]*sinf(zRowRad); camPos[1] += 0.5f*camPosKeyDown[1]*cosf(zRowRad); camPos[2] += 0.5f*camPosKeyDown[2]; //load identity glLoadIdentity(); //set clear color glClearColor(0, 0, 0, 1); //clear specified buffers // GL_COLOR_BUFFER_BIT - color writing buffers // GL_DEPTH_BUFFER_BIT - depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //translate and rotate for camera glRotatef(-camRot[0], 1, 0, 0); glRotatef(-camRot[1], 0, 1, 0); glRotatef(-camRot[2], 0, 0, 1); glTranslatef(-camPos[0], -camPos[1], -camPos[2]); //push the current matrix //NOTE: This is useless for this particular application, since there //is ONLY 1 static object at the origin. glPushMatrix(); //move the position of the object //glTranslatef(200.0f, 0, 0); //draw SierpinskiGasket3f(300.0f, 7); //pop the current matrix glPopMatrix(); //swap buffers glutSwapBuffers(); } void SierpinskiGasket3f(float _rad, int _count) { float points0Arr[3] = {_rad, 0, 0}; float points1Arr[3] = {_rad*(-0.5f), _rad*(0.866025404f), 0}; float points2Arr[3] = {_rad*(-0.5f), _rad*(-0.866025404f), 0}; float points3Arr[3] = {0, 0, _rad}; glBegin(GL_TRIANGLES); SierpinskiGasket3f_A(points0Arr, points1Arr, points2Arr, points3Arr, _count); glEnd(); } void SierpinskiGasket3f_A(float _point0Arr[], float _point1Arr[], float _point2Arr[], float _point3Arr[], int _count) { if(_count > 0) { //reduce count _count -= 1; //new points array float newPoint01Arr[3]; float newPoint12Arr[3]; float newPoint20Arr[3]; float newPoint03Arr[3]; float newPoint13Arr[3]; float newPoint23Arr[3]; //fill points SierpinskiGasket3f_LineMidPoint(newPoint01Arr, _point0Arr, _point1Arr); SierpinskiGasket3f_LineMidPoint(newPoint12Arr, _point1Arr, _point2Arr); SierpinskiGasket3f_LineMidPoint(newPoint20Arr, _point2Arr, _point0Arr); SierpinskiGasket3f_LineMidPoint(newPoint03Arr, _point0Arr, _point3Arr); SierpinskiGasket3f_LineMidPoint(newPoint13Arr, _point1Arr, _point3Arr); SierpinskiGasket3f_LineMidPoint(newPoint23Arr, _point2Arr, _point3Arr); // sub-triangle 1 SierpinskiGasket3f_A(newPoint01Arr, _point1Arr, newPoint12Arr, newPoint13Arr, _count); // sub-triangle 2 SierpinskiGasket3f_A(newPoint12Arr, _point2Arr, newPoint20Arr, newPoint23Arr, _count); // sub-triangle 3 SierpinskiGasket3f_A(newPoint01Arr, _point0Arr, newPoint20Arr, newPoint03Arr, _count); // sub-triangle 4 SierpinskiGasket3f_A(newPoint03Arr, newPoint13Arr, newPoint23Arr, _point3Arr, _count); } else { //draw faces //side 0 (bottom) glColor4f(1, 0, 0, 1); //0 glVertex3fv(_point0Arr); glColor4f(0, 1, 0, 1); //1 glVertex3fv(_point1Arr); glColor4f(0, 0, 1, 1); //2 glVertex3fv(_point2Arr); //side 1 glColor4f(1, 0, 0, 1); //0 glVertex3fv(_point0Arr); glColor4f(0, 1, 0, 1); //1 glVertex3fv(_point1Arr); glColor4f(0.7, 0.7, 0.7, 1); //3 glVertex3fv(_point3Arr); //side 2 glColor4f(0, 1, 0, 1); //1 glVertex3fv(_point1Arr); glColor4f(0, 0, 1, 1); //2 glVertex3fv(_point2Arr); glColor4f(0.7, 0.7, 0.7, 1); //3 glVertex3fv(_point3Arr); //side 3 glColor4f(0, 0, 1, 1); //2 glVertex3fv(_point2Arr); glColor4f(1, 0, 0, 1); //0 glVertex3fv(_point0Arr); glColor4f(0.7, 0.7, 0.7, 1); //3 glVertex3fv(_point3Arr); } } void SierpinskiGasket3f_LineMidPoint(float _midPointOut[], float _point0Arr[], float _point1Arr[]) { _midPointOut[0] = (_point0Arr[0] + _point1Arr[0]) / 2; _midPointOut[1] = (_point0Arr[1] + _point1Arr[1]) / 2; _midPointOut[2] = (_point0Arr[2] + _point1Arr[2]) / 2; }
-lglut32 -lglu32 -lopengl32 -lwinmm -lgdi32
perhatikan gambar berikut ini.
Mudah kan sobat? karena saya masih pemula, saya tunggu kritik dan sarannya. Semoga bermanfaat ^_^
Referensi : http://www.st0rm.net/forum/showthread.php?12001-3D-Sierpinski-Gasket-(OpenGL)
enggak ngerti gan T_T
BalasHapusbermanfaat pak :-D a basstaaaaa!!!
BalasHapusmcm mana mau bg dia tukar warna?
BalasHapus