OpenGL/Kiub Berputar

Daripada Wikibooks
Pergi ke navigasi Pergi ke carian

Kod sumber berikut adalah untuk memaparkan sebuah kiub yang berputar.

#include <stdio.h> 
#include <GL/glut.h>

static GLfloat theta[]= {0.0, 0.0, 0.0};
static GLint axis = 2;

GLfloat vertices[][3] = {
	{-1.0, -1.0, -1.0},
	{ 1.0, -1.0, -1.0},
	{ 1.0,  1.0, -1.0},
	{-1.0,  1.0, -1.0},
	{-1.0, -1.0,  1.0},
	{ 1.0, -1.0,  1.0},
	{ 1.0,  1.0,  1.0},
	{-1.0,  1.0,  1.0}

};

GLfloat colors[][3] = {		
	{0.0, 0.0, 0.0},
	{1.0, 0.0, 0.0},
	{0.0, 1.0, 0.0},
	{0.0, 0.0, 1.0},
	{1.0, 1.0, 0.0},
	{1.0, 0.0, 1.0},
	{0.0, 1.0, 1.0},
	{1.0, 1.0, 1.0}

};

void polygon (int a, int b, int c, int d){

		glColor3fv(colors[a]);
		glVertex3fv(vertices[a]);

		glColor3fv(colors[b]);
		glVertex3fv(vertices[b]);

		glColor3fv(colors[c]);
		glVertex3fv(vertices[c]);

		glColor3fv(colors[d]);
		glVertex3fv(vertices[d]);

	glEnd();

}

void colorcube(void){

	polygon(0, 3, 2, 1);
	polygon(2, 3, 7, 6);
	polygon(0, 4, 7, 3);
	polygon(1, 2, 6, 5);
	polygon(4, 5, 6, 7);
	polygon(0, 1, 5, 4);
}

void display(void){
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glLoadIdentity();			

	glRotatef(theta[0], 1.0, 0.0, 0.0);
	glRotatef(theta[1], 0.0, 1.0, 0.0);
	glRotatef(theta[2], 0.0, 0.0, 1.0);

	colorcube();

	glFlush();				

	glutSwapBuffers();			
}


void spinCube(void){

	

	theta[axis] += 0.05;
	if(theta[axis] > 360.0){
		theta [axis] -= 360.0;
	}

	display();

}

void mouse(int btn, int state, int x, int y){

	
	if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN){axis = 0;}
	if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){axis = 1;}
	if(btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN){axis = 3;}

}

void myReshape(int w, int h){

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();	
	if( w <= h){
		glOrtho( -2.0, 2.0, -2.0*((GLfloat)h/(GLfloat)w), 
			2.0*((GLfloat)h/(GLfloat)w), -10.0, 10.0);

	}else{
		glOrtho( -2.0*((GLfloat)w/(GLfloat)h), 2.0*((GLfloat)w/(GLfloat)h), -2.0,
			2.0, -10.0, 10.0);
	}

	glMatrixMode(GL_MODELVIEW);	

}

int main(int argc, char **argv){

		glutInit(&argc, argv);

		glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
		glutInitWindowSize( 500, 500);
		glutCreateWindow("Kiub Berputar");
		glutReshapeFunc(myReshape);
		glutDisplayFunc(display);
		glutIdleFunc(spinCube);
		glutMouseFunc(mouse);
		glEnable(GL_DEPTH_TEST);			

		glutMainLoop();

		return 0;

}

Penerangan Selanjutnya

#include <stdio.h>

Kod di atas bertujuan untuk mengambil kandungan fail yang dinamakan “stdio.h “dan melekatkannya di dalam fail sumber. Pada asasnya, ia memberitahu pengkompil untuk membuat perpustakaan “stdio.h” disediakan supaya fungsi-fungsi boleh digunakan dalam kod. Stdio.h termasuk semua fungsi standard I / O (seperti membenarkan input keyboard, dll)

#include <GL/glut.h><br>

Begitu juga dengan kod di atas. Bezanya ianya diambil dari fail “glut.h”.

Berikut adalah untuk menetapkan putaran sudut awal.

static GLfloat theta[]= {0.0, 0.0, 0.0};

Di bawah pula adalah untuk menetapkan paksi awal putaran.

static GLint axis = 2;

Kod berikut pula adalah untuk mencipta 8 bucu atau mercu sesebuah kiub.

GLfloat vertices[][3] = {		
	{-1.0, -1.0, -1.0},
	{ 1.0, -1.0, -1.0},
	{ 1.0,  1.0, -1.0},
	{-1.0,  1.0, -1.0},
	{-1.0, -1.0,  1.0},
	{ 1.0, -1.0,  1.0},
	{ 1.0,  1.0,  1.0},
	{-1.0,  1.0,  1.0}

};

Kod seterusnya pula adalah untuk memberi warna kepada setiap bucu. Warna adalah berdasarkan RGB-Merah, Hijau, dan Biru.

GLfloat colors[][3] = {			 
       {0.0, 0.0, 0.0},  // -hitam
	{1.0, 0.0, 0.0}, // -merah
	{0.0, 1.0, 0.0}, // -hijau
	{0.0, 0.0, 1.0}, // -biru
	{1.0, 1.0, 0.0}, // -kuning
	{1.0, 0.0, 1.0}, // -magenta merah jambu keunguan
	{0.0, 1.0, 1.0}, // -cyan atau biru hijau
	{1.0, 1.0, 1.0}  // -putih

};

Kod-kod di bawah pula untuk melukis sisi kiub dan menetapkan warna.

void polygon (int a, int b, int c, int d){

	glBegin(GL_POLYGON);

		glColor3fv(colors[a]);
		glVertex3fv(vertices[a]);

		glColor3fv(colors[b]);
		glVertex3fv(vertices[b]);

		glColor3fv(colors[c]);
		glVertex3fv(vertices[c]);

		glColor3fv(colors[d]);
		glVertex3fv(vertices[d]);

	glEnd();

}

Seterusnya adalah untuk menetapkan peta dan koordinat bucu. Diingatkan bahawa susunannya amat penting bagi menetapkan bentuk kiub tersebut.

void colorcube(void){
	polygon(0, 3, 2, 1);
	polygon(2, 3, 7, 6);
	polygon(0, 4, 7, 3);
	polygon(1, 2, 6, 5);
	polygon(4, 5, 6, 7);
	polygon(0, 1, 5, 4);
}

Berikut adalah untuk memanggil balik paparan, menghilangkan penampan rangka dan penampan z, memutarkan kiub dan melukis kiub tersebut.

void display(void){

Berikut pula untuk menhilangkan penampan pusat pandangan iaitu penampan warna dan kedalaman.

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

Kod di bawah pula untuk menggantikan matrix semasa dengan matrix persamaan(identiti). atau untuk melihat bayang-bayang imej terakhir.

	glLoadIdentity();

Kod seterusnya adalah untuk menggandakan matrix semasa dengar matrix putaran, theta, x, y, z.

	glRotatef(theta[0], 1.0, 0.0, 0.0);
	glRotatef(theta[1], 0.0, 1.0, 0.0);
	glRotatef(theta[2], 0.0, 0.0, 1.0);

	colorcube();

Pelaksanaan berkuat kuasa arahan GL dalam masa yang yang terbatas adalah seperti berikut.

	glFlush();

Bertujuan meletakkan imej untuk dilukis di penampan sebagai paparan.

	glutSwapBuffers();			

}

Berikut pula adalah unuk memanggil balik idle dan memutar kiub sebanyak 2 darjah.

void spinCube(void){

	theta[axis] += 0.05;

Meletakkan darjah rangka lebih kecil bermaksud memperlahankan pusingan kiub.

	if(theta[axis] > 360.0){
		theta [axis] -= 360.0;
	}

	display();

}

Kod di bawah pula adalah untuk memilih satu paksi untuk berputar.

void mouse(int btn, int state, int x, int y){

	if(btn == GLUT_LEFT_BUTTON && state == GLUT_DOWN){axis = 0;}
	if(btn == GLUT_RIGHT_BUTTON && state == GLUT_DOWN){axis = 1;}
	if(btn == GLUT_MIDDLE_BUTTON && state == GLUT_DOWN){axis = 3;}


}
void myReshape(int w, int h){

glViewport( 0, 0, w, h); //Menetapkan pusat pandangan. Tidak diperlukan untuk kod sumber ini.

Untuk memilih matrik timbunan tertentu untuk melaksanakan operasi berikutnya.

	glMatrixMode(GL_PROJECTION);

Mengurangkan kelip-kelip tetapi tidak meninggalkan impak besar di dalam program ini.

	glLoadIdentity();

	if( w <= h){
		glOrtho( -2.0, 2.0, -2.0*((GLfloat)h/(GLfloat)w), 
			2.0*((GLfloat)h/(GLfloat)w), -10.0, 10.0);

	}else{
		glOrtho( -2.0*((GLfloat)w/(GLfloat)h), 2.0*((GLfloat)w/(GLfloat)h), -2.0,
			2.0, -10.0, 10.0);
	}

Bertukar kepada operasi matrix pandangan model.

	glMatrixMode(GL_MODELVIEW);

}
int main(int argc, char **argv){

		glutInit(&argc, argv);

Tetapkan mod paparan penciptaan tingkap. Ia juga membolehkan anda untuk mengawal cara tingkap openGL berikutnya.
GLUT_DOUBLE penting untuk animasi yang lancar. GLUT_RGB untuk warna default. GLUT_DEPTH untuk penampan kedalaman.

		glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); //paparan penampan berganda, rgb dan kedalaman

Menetapkan saiz tingkap ukuran 500x500

		glutInitWindowSize( 500, 500);

Memmberi nama kepada tingkap iaitu "Kiub Berputar"

		glutCreateWindow("Kiub Berputar");

glutReshapeFunc set panggil balik membentuk semula bagi tetingkap semasa.Panggil balik membentuk semula dicetuskan apabila tingkap membentuk semula.
Sebuah panggil balik membentuk semula adalah juga dicetuskan sebaik sebelum panggil balik pertama dipaparkan tetingkap selepas tingkap yang diwujudkan atau bila-bila masa lapisan untuk tingkap ditubuhkan.
Parameter lebar dan ketinggian panggil balik yang menentukan saiz tetingkap baru dalam piksel.Sebelum panggil balik, tetingkap semasa ke tingkap yang telah membentuk semula.

		glutReshapeFunc(myReshape);

glutDisplayFunc set panggil balik paparan tetingkap semasa. Apabila GLUT menentukan bahawa satah biasa untuk tingkap perlu dipaparkan semula, panggil balik paparan untuk tingkap dipanggil.

		glutDisplayFunc(display);

glutIdleFunc menetapkan panggil balik idle global supaya program GLUT boleh melaksanakan tugas pemprosesan latar belakang atau animasi berterusan apabila peristiwa sistem tetingkap tidak diterima.
Jika diaktifkan, panggilan balik idle terus dipanggil apabila peristiwa tidak diterima. Rutin panggil balik tidak mempunyai parameter. Tetingkap semasa dan menu semasa tidak akan berubah sebelum panggil balik idle.

		glutIdleFunc(spinCube);

glutMouseFunc set panggil balik tetikus untuk tingkap semasa.

		glutMouseFunc(mouse);

Membolehkan pembuangan permukaan tersembunyi.

		glEnable(GL_DEPTH_TEST);

glutMainLoop memasukkan pemprosesan GLUT gelung. Rutin ini harus dipanggil paling banyak sekali dalam program GLUT. Sebaik sahaja dipanggil, rutin ini tidak akan kembali. Ia akan memanggil perlu apa-apa panggilan balas yang telah berdaftar.

			
		glutMainLoop();


		return 0;

}

Diharapkan penjelasan di atas dapat membantu sedikit sebanyak pemahaman anda ke atas kod sumber openGL kiub berputar.

Lihat juga[sunting]