OpenGL/Pengenalan Penggunaan OpenGL

Daripada Wikibooks

Laman ini disunting untuk memberi penerangan mengenai atur cara menggunakan OpenGL.

Aturcara ini adalah untuk menunjukkan penggunaan ringkas OpenGl untuk membuat animasi gerakan.

Apabila aturcara ini dijalankan, ia akan menghasilkan animasi putaran segi tiga yang bertindih.

Cara penggunaan[sunting]

Tekan kekunci "r" untuk memulakan animasi atau menghentikannya.

Tekan kekunci "s" untuk mengaktifkan animasi satu langkah.

Tekan kekunci anak panah atas dan bawah untuk mengawal kelajuan animasi putaran.

Tekan kekunci "esc" untuk keluar.


Atur cara[sunting]

#include <math.h>		// untuk penggunaan fungsi matematik.
#include <stdio.h>        // fail kepala bagi membolehkan penggunaan Library "C"
#include <stdlib.h>	// untuk fungsi keluar
#include <GL/glut.h>	// OpenGL Graphics Utility Library
#include "SimpleAnim.h"   // fail kepala bagi membolehkan animasi berlaku

int RunMode = 1;		// diguna sebagai boolean (1 atau 0) untuk "buka" dan "tutup"

// pembolehubah global yang mengawal keadaan dan kelajuan animasi.

float CurrentAngle = 0.0f;		// sudut dalam darjah
float AnimateStep = 3.0f;			// kadar putaran

// pembolehubah bagi dimensi kawasan yang nampak.
const double Xmin = 0.0, Xmax = 3.0;
const double Ymin = 0.0, Ymax = 3.0;

//glutKeyboardFunc merupakan fungsi yang dipanggil untuk mengendalikan input daripada pengguna.

void myKeyboardFunc( unsigned char key, int x, int y )
{
	switch ( key ) {
	case 'r':
		RunMode = 1-RunMode;		// memberikan nilai yang berlawanan
		if ( RunMode==1 ) {
			glutPostRedisplay();
		}
		break;
	case 's':
		RunMode = 1;
		drawScene();
		RunMode = 0;
		break;
	case 27:	// kekunci "esc"
		exit(1);
	}
}

// glutSpecialFunc adalah fungsi yang dpanggil untuk mengendalikan input dari pengguna untuk anak panah atas dan bawah.

void mySpecialKeyFunc( int key, int x, int y )
{
	switch ( key ) {
	case GLUT_KEY_UP:		
		if ( AnimateStep < 1.0e3) {			// mengelakkan masalah overflow
			AnimateStep *= sqrt(2.0);		// menaikkan penambahan sudut
		}
		break;
	case GLUT_KEY_DOWN:
		if (AnimateStep>1.0e-6) {		// mengelakkan masalah overflow
			AnimateStep /= sqrt(2.0);	// mengurangkan penambahan sudit
		}
		break;
	}
}

drawScene() merupakan fungsi yang mengendalikan animasi dan pelukisan semula grafik.

 
void drawScene(void)
{
	//mengosongkan tingkap
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    if (RunMode==1) {
		// mengira parameter animasi 
        CurrentAngle += AnimateStep;
		if ( CurrentAngle > 360.0 ) {
			CurrentAngle -= 360.0*floor(CurrentAngle/360.0);	// bagi mengelakkan overflow
		}
	}
	
	// '''memusingkan imej'''
	glMatrixMode( GL_MODELVIEW );			// posisi objek semasa
	glLoadIdentity();						// menghasilkan imej
	glTranslatef( 1.5, 1.5, 0.0 );					// translasi putaran pusat dari asalan
	glRotatef( CurrentAngle, 0.0, 0.0, 1.0 );		// putaran sudut animasi
	glTranslatef( -1.5, -1.5, 0.0 );				// translasi putaran pusat dari asalan

	// membina tiga segitiga bertindih yang berlainan warna
	glBegin( GL_TRIANGLES );
	glColor3f( 1.0, 0.0, 0.0 );
	glVertex3f( 0.3, 1.0, 0.5 );
	glVertex3f( 2.7, 0.85, 0.0 );
	glVertex3f( 2.7, 1.15, 0.0 );

	glColor3f( 0.0, 1.0, 0.0 );
	glVertex3f(2.53, 0.71, 0.5 );
	glVertex3f(1.46, 2.86, 0.0 );
	glVertex3f(1.2, 2.71, 0.0 );

	glColor3f( 0.0, 0.0, 1.0 );
	glVertex3f(1.667, 2.79, 0.5);
	glVertex3f(0.337, 0.786, 0.0);
	glVertex3f(0.597, 0.636, 0.0);
	glEnd();

	// menukar pemampan (buffer)
    glFlush();
    glutSwapBuffers();

	if ( RunMode==1 ) {
		glutPostRedisplay();	// menyebabkan penghasilan semula grafik untuk animasi
	}

}

// memulakan mode render OpenGL
void initRendering()
{
    glShadeModel( GL_FLAT );	// nilai cadangan yang telah ditetap
    glEnable( GL_DEPTH_TEST );	// pengujian kedalaman mesti diaktif
}

// dipanggil apabila saiz tingkap diubah
void resizeWindow(int w, int h)
{
	double scale, center;
	double windowXmin, windowXmax, windowYmin, windowYmax;

	// menyatakan bahagian yang diguna untuk OpenGL rendering.
	glViewport( 0, 0, w, h );	// View port megguna keseluruhan tingkap\

  //menetapkan nilai w dan h untuk projection view matrix
	w = (w==0) ? 1 : w;
	h = (h==0) ? 1 : h;
	if ( (Xmax-Xmin)/w < (Ymax-Ymin)/h ) {
		scale = ((Ymax-Ymin)/h)/((Xmax-Xmin)/w);
		center = (Xmax+Xmin)/2;
		windowXmin = center - (center-Xmin)*scale;
		windowXmax = center + (Xmax-center)*scale;
		windowYmin = Ymin;
		windowYmax = Ymax;
	}
	else {
		scale = ((Xmax-Xmin)/w)/((Ymax-Ymin)/h);
		center = (Ymax+Ymin)/2;
		windowYmin = center - (center-Ymin)*scale;
		windowYmax = center + (Ymax-center)*scale;
		windowXmin = Xmin;
		windowXmax = Xmax;
	}

	//memulakan projection matrix apabila mendapat nilai.
    glMatrixMode( GL_PROJECTION );
    glLoadIdentity();
    glOrtho( windowXmin, windowXmax, windowYmin, windowYmax, -1, 1 );

}


// memulakan loop utama
int main( int argc, char** argv )
{
	glutInit(&argc,argv);

	// pemampan berganda disebabkan berlaku animasi 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );

	// kedudukan tingkap
    glutInitWindowPosition( 10, 60 );
    glutInitWindowSize( 360, 360 );
    glutCreateWindow( "Animasi 3 segitiga" ); //nama tingkap

	// memulakan OpenGL
    initRendering();

	// menetapkan fungsi apabila kunci ditekan
	glutKeyboardFunc( myKeyboardFunc );			// mengendalikan simbol ascii yang biasa
	glutSpecialFunc( mySpecialKeyFunc );		        // mengendali kekunci khas

	// menetapkan panggilan fungsi untuk menukar saiz tingkap
    glutReshapeFunc( resizeWindow );

	// memanggil fungsi ini apabila tiada arahan untuk pemprosesan
	  glutIdleFunc( myIdleFunction );

	// memanggil fungsi ini apabila tingkap memerlukan penghasilan semula grafik
    glutDisplayFunc( drawScene );

	fprintf(stdout, "Kekunci Anak Panah untuk mengawal kelajuan.Tekan \"r\" untuk mula,  \"s\" untuk langkah demi langkah.\n");
	
	// memulakan ulangan utama (main)
	glutMainLoop(  );

    return(0);	// akhir dari aturcara
}

Rujukan[sunting]

Oleh :

A134440
Asas Teknik Rekabentuk Berkomputer
Universiti Kebangsaan Malaysia