Kompyuter grafikasi: OpenGL 2-qism

Kompyuter grafikasi: OpenGL 2-qism

Salom. Bugun yana o’sha kompyuter grafikasi haqida gapirmoqchiman. Oldingiz maqolamni o’qigan bo’lsangiz u yerda faqat matematika haqida gapirganman. Endi shu matematikani haqiqiy dasturlashda ko’ramiz.

Buning uchun bizga yana OpenGL va SDL kerak bo’ladi.

Avvalo VS2010 da bitta Console Application (C/C++) yaratib, main.cpp ni ham qo’shamiz o’sha proyektga va ishni boshlaymiz.

Asosiy ishimiy matritsalar bilan ishlash bo’ladi.

Matritsani strukturasini yaratish

typedef struct _MATRIX
{
	int n, m; /* Matritsani o'lchami */
	double ** data; /* Matritsa qiymatlari */
} MATRIX, * PMATRIX;

Endi yangi matritsani yaratadigan ya o’chirish funksiyani

PMATRIX new_matrix(int n, int m)
{
	PMATRIX pm = (PMATRIX)malloc(sizeof(_MATRIX));
	pm->data = (double **)malloc(n * sizeof(double));
	pm->n = n;
	pm->m = m;

	for(int i = 0; i data[i] = (double *)malloc(m * sizeof(double));
		for(int j = 0; j data[i][j] = i == j ? 1 : 0;
	}

	return pm;
}

void free_matrix(PMATRIX pm)
{
	free(pm->data);
	pm->data = NULL;

	free(pm);
	pm = NULL;
}

Eng ko’p ishlatiladigan funksiyamiz ya’ni matritsalarni ko’paytirish

void mult(PMATRIX m1, PMATRIX *m2)
{
	PMATRIX result = new_matrix((*m2)->n, (*m2)->m);
	for(int nn = 0; nn n; nn++)
	{
		for(int mm = 0; mm m; mm++)
		{
			result->data[nn][mm] = 0;
			for(int k = 0; k n; k++)
				result->data[nn][mm] += m1->data[nn][k] * (*m2)->data[k][mm];
		}
	}

	free_matrix(*m2);
	*m2 = result;
}

Asosiy funksiyalar transform va rotate (scaleni yozmadim)

void transform(PMATRIX *point, int dx, int dy, int dz)
{
	PMATRIX m = new_matrix(4, 4); 
	m->data[0][3] = dx;
	m->data[1][3] = dy;
	m->data[2][3] = dz;

	mult(m, point);

	free_matrix(m);
}

void rotate(PMATRIX *point, double x, double y, double z, float angle)
{
	angle = angle * 3.1415926 / 180.0;

	PMATRIX rX = new_matrix(4, 4); 
	rX->data[1][1] = cos(angle * x);
	rX->data[2][1] = sin(angle * x);
	rX->data[1][2] = -sin(angle * x);
	rX->data[2][2] = cos(angle * x);

	PMATRIX rY = new_matrix(4, 4); 
	rY->data[0][0] = cos(-angle * y);
	rY->data[2][0] = sin(-angle * y);
	rY->data[0][2] = -sin(-angle * y);
	rY->data[2][2] = cos(-angle * y);

	PMATRIX rZ = new_matrix(4, 4); 
	rZ->data[0][0] = cos(angle * z);
	rZ->data[1][0] = sin(angle * z);
	rZ->data[0][1] = -sin(angle * z);
	rZ->data[1][1] = cos(angle * z);

	if (x != 0.0)
		mult(rX, point);

	if (y != 0.0)
		mult(rY, point);

	if (z != 0.0)
		mult(rZ, point);

	free_matrix(rX);
	free_matrix(rY);
	free_matrix(rZ);
}

Yana 2 ta funksiyami qoldi, ular kordinalatalar oqi va nuqtani chizish uchun ishlatiladi. Mani holatimda n — matritsani qatorlari soni, m — ustunlari soni sifatida ishlatilgan. Kodda izoh keltirmadim chunki bundan oldingi maqolamda hamma matritsalarni keltirganman. Shularni faqat kodga o’tkazdim. Qolga sizga notanish funksiyalar bilan asta sekin tanishamiz.

Shunaq qilib oxirgi natija:

#include 
#include 
#include 

#include 
#include 
#include 

#include 
#define PROGRAM_NAME "Matritsalar"


typedef struct _MATRIX
{
	int n, m; /* Matritsani o'lchami */
	double ** data; /* Matritsa qiymatlari */
} MATRIX, * PMATRIX;

PMATRIX new_matrix(int n, int m)
{
	PMATRIX pm = (PMATRIX)malloc(sizeof(_MATRIX));
	pm->data = (double **)malloc(n * sizeof(double));
	pm->n = n;
	pm->m = m;

	for(int i = 0; i data[i] = (double *)malloc(m * sizeof(double));
		for(int j = 0; j data[i][j] = i == j ? 1 : 0;
	}

	return pm;
}

void free_matrix(PMATRIX pm)
{
	free(pm->data);
	pm->data = NULL;

	free(pm);
	pm = NULL;
}

void mult(PMATRIX m1, PMATRIX *m2)
{
	PMATRIX result = new_matrix((*m2)->n, (*m2)->m);
	for(int nn = 0; nn n; nn++)
	{
		for(int mm = 0; mm m; mm++)
		{
			result->data[nn][mm] = 0;
			for(int k = 0; k n; k++)
				result->data[nn][mm] += m1->data[nn][k] * (*m2)->data[k][mm];
		}
	}

	free_matrix(*m2);
	*m2 = result;
}


void transform(PMATRIX *point, int dx, int dy, int dz)
{
	PMATRIX m = new_matrix(4, 4); 
	m->data[0][3] = dx;
	m->data[1][3] = dy;
	m->data[2][3] = dz;

	mult(m, point);

	free_matrix(m);
}

void rotate(PMATRIX *point, double x, double y, double z, float angle)
{
	angle = angle * 3.1415926 / 180.0;

	PMATRIX rX = new_matrix(4, 4); 
	rX->data[1][1] = cos(angle * x);
	rX->data[2][1] = sin(angle * x);
	rX->data[1][2] = -sin(angle * x);
	rX->data[2][2] = cos(angle * x);

	PMATRIX rY = new_matrix(4, 4); 
	rY->data[0][0] = cos(-angle * y);
	rY->data[2][0] = sin(-angle * y);
	rY->data[0][2] = -sin(-angle * y);
	rY->data[2][2] = cos(-angle * y);

	PMATRIX rZ = new_matrix(4, 4); 
	rZ->data[0][0] = cos(angle * z);
	rZ->data[1][0] = sin(angle * z);
	rZ->data[0][1] = -sin(angle * z);
	rZ->data[1][1] = cos(angle * z);

	if (x != 0.0)
		mult(rX, point);

	if (y != 0.0)
		mult(rY, point);

	if (z != 0.0)
		mult(rZ, point);

	free_matrix(rX);
	free_matrix(rY);
	free_matrix(rZ);
}

void draw_coords()
{
	glBegin(GL_LINES);

	glColor3ub(255, 0, 0);
	glVertex3i(-50, 0, 0);
	glVertex3i(100, 0, 0);

	glColor3ub(0, 255, 0);
	glVertex3i(0, -50, 0);
	glVertex3i(0, 100, 0);

	glColor3ub(0, 0, 255);
	glVertex3i(0, 0, -50);
	glVertex3i(0, 0, 100);

	glEnd();
}

void draw_matrix_point(PMATRIX m)
{
	int x = m->data[0][0];
	int y = m->data[1][0];
	int z = m->data[2][0];

	glBegin(GL_QUADS);

	glColor3ub(255, 255, 0);

	//past qismi
	glVertex3i(x - 1, y - 1, z - 1);
	glVertex3i(x + 1, y - 1, z - 1);
	glVertex3i(x + 1, y + 1, z - 1);
	glVertex3i(x - 1, y + 1, z - 1);

	//yuqorisi
	glVertex3i(x - 1, y - 1, z + 1);
	glVertex3i(x + 1, y - 1, z + 1);
	glVertex3i(x + 1, y + 1, z + 1);
	glVertex3i(x - 1, y + 1, z + 1);

	glVertex3i(x - 1, y - 1, z - 1);
	glVertex3i(x + 1, y - 1, z - 1);
	glVertex3i(x + 1, y - 1, z + 1);
	glVertex3i(x - 1, y - 1, z + 1);

	glVertex3i(x - 1, y + 1, z - 1);
	glVertex3i(x + 1, y + 1, z - 1);
	glVertex3i(x + 1, y + 1, z + 1);
	glVertex3i(x - 1, y + 1, z + 1);

	glVertex3i(x - 1, y - 1, z - 1);
	glVertex3i(x - 1, y - 1, z + 1);
	glVertex3i(x - 1, y + 1, z + 1);
	glVertex3i(x - 1, y + 1, z - 1);


	glVertex3i(x + 1, y - 1, z - 1);
	glVertex3i(x + 1, y - 1, z + 1);
	glVertex3i(x + 1, y + 1, z + 1);
	glVertex3i(x + 1, y + 1, z - 1);

	glEnd();
}

void sdldie(const char *msg)
{
    printf("%s: %sn", msg, SDL_GetError());
    SDL_Quit();
    exit(1);
}

int main(int argc, char *argv[])
{
	//X=50, Y=0, Z=50 joydagi nuqta matritsasini yaratish
	PMATRIX point = new_matrix(4, 1);
	point->data[0][0] = 50;
	point->data[1][0] = 0;
	point->data[2][0] = 50;
	point->data[3][0] = 1;

	int windowWidth = 640, windowHeight = 480;
	int isRunning = 1;

	SDL_Window *mainwindow; /* Oynda o'zgaruvchisi */
    SDL_GLContext maincontext; /* OpenGL konteksi o'zgaruvchisi */

    if (SDL_Init(SDL_INIT_VIDEO) 

Natija (EXE ko'chirish):

9ac68a

Sizga vaxima bo'lib ko'rinayotgan kodda aslida hech narsa yozilmagan desayam bo'ladi. Keyingi maqolamda huddi shu natijani OpenGL ni funksiyalaridan foydalanib qilamiz.

Texnologiyalar
Kompyuter grafikasi: OpenGL 2-qism