OpenGL - 비주얼 스튜디오(VS)에 설치!

windows10, visual studio 2017 환경입니다.


1. 첨부된 파일을 받습니다.


2. 압축을 해제 합니다.


3. *.lib 파일은 C:\Program Files (x86)\Windows Kits\10\Lib\10.0.15063.0\um\x86 에 모두 paste 합니다.


4. *.h 파일은 C:\Program Files (x86)\Windows Kits\10\Include\10.0.15063.0\um\gl 에 모두 paste 합니다.

(gl 폴더가 없다면 생성 후 paste 하면 된다.)


5. *dll 파일은 모두 C:\Windows\System32 에 paste 합니다.


6. VS에서 OpenGL 프로젝트를 생성할 때 소스코드 상단에 아래와 같이 작성한다.


#include <Windows.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <gl/glut.h>
#include <gl/glaux.h>

순서가 다르면 안되는 경우도 있다고 한다. 


혹시 순서가 다르다면 순서를 같게 해본다.



opengl_lib.zip


OpenGL - 큐브회전 (X, Y, Z), 문자출력

설명


3차원 큐브를 X축, Y축, Z축 회전을 하며 (x, y, z키를 눌렀을 경우),


X, Y, Z를 눌렀을 때 우측 하단에 문자열을 출력한다.



소스코드

(앞의 예제와 마찬가지로 생략된 부분은 아래의 링크를  참조한다.)

2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기


변수

static bool R = true;
static bool G = true;
static bool B = true;
static float theta;
bool rot = true;
int rx_axis = 0y_axis = 1z_axis = 0;
int t_xt_yt_z;
 
/// <summary>
/// The vertices {x, y, z}
/// </summary>
GLfloat vertices[8][3] = { { -1, -11 },{ -111 },
{ 111 },{ 1, -11 },{ -1, -1, -1 },
{ -11, -1 },{ 11, -1 },{ 1, -1, -1 } };
 
/// <summary>
/// The colors {R, G, B}
/// </summary>
GLfloat colors[8][3] =
{ { 001 },{ 011 },
{ 111 },{ 101 },
{ 000 },{ 010 },
{ 110 },{ 100 } };


키보드 이벤트

void menu(int item)
{
	keyboard((unsigned char)item00);
}
 
void keyupfunc(unsigned char keyint xint y)
{
	t_x = 0;
	t_y = 0;
	t_z = 0;
}
 
void keyboard(unsigned char keyint xint y)
{
	switch (key)
	{
	case 'q' | 'Q':
		exit(0); break;
	case VK_ESCAPE:
		exit(0); break;
	case 'x' | 'X'//rotate with x axis
	{
		x_axis = 1;
		y_axis = 0;
		z_axis = 0;
		t_x = 1;
		t_y = 0;
		t_z = 0;
		break;
	}
	case 'y' | 'Y'//rotate with y axis
	{
		x_axis = 0;
		y_axis = 1;
		z_axis = 0;
		t_x = 0;
		t_y = 1;
		t_z = 0;
		break;
	}
	case 'z' | 'Z'//rotate with z axis
	{
		x_axis = 0;
		y_axis = 0;
		z_axis = 1;
		t_x = 0;
		t_y = 0;
		t_z = 1;
		break;
	}
	default:
		break;
	}
}


렌더링함수

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.50.50.5000010);
 
	glPushMatrix(); {//push
		glRotatef(thetax_axisy_axisz_axis);
		//draw cube
		quad(0321);
		quad(2376);
		quad(3047);
		quad(1265);
		quad(4567);
		quad(5401);
		glEnd();
	}glPopMatrix();//pop
 
	glPushMatrix(); {//push
		glColor3f(100);//red
		glRasterPos2f(1.4, -1.4);//string position
		if (t_x == 1)//print X_axis
			glPrint("X_axis"theta);
		else if (t_y == 1)//print Y_axis
			glPrint("Y_axis"theta);
		else if (t_z == 1)//print Z_axis
			glPrint("Z_axis"theta);
	}glPopMatrix();//pop
 
	glutPostRedisplay();
	glutSwapBuffers();
}
//swap rotate direction
void mouseButton(int buttonint stateint xint y)
{
	if (button == GLUT_LEFT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
			if (!mouseLeftDown)
			{
				if (rot)
					rot = false;
				else
					rot = true;
			}
		}
		else if (state == GLUT_UP)
		{
			if (mouseLeftDown)
				mouseLeftDown = false;
		}
	}
	else if (button == GLUT_RIGHT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
		}
		else if (state = GLUT_UP)
		{
		}
	}
	glutPostRedisplay();
}
 
void mouseMotion(int xint y)
{
	if (mouseLeftDown)
	{
		double viewport[4];
		glGetDoublev(GL_VIEWPORTviewport);
 
		point[1][0] = x / (float)viewport[2] * 500;
		point[1][1] = (viewport[3] - y) / (float)viewport[3] * 500;
	}
	glutPostRedisplay();
}


폰트 설정

//setting font
void init(void)
{
	theta = 0.0f;
	hWnd = GetActiveWindow();
	hDC = GetDC(hWnd);
 
	listID = glGenLists(1);
	glNewList(listIDGL_COMPILE);
 
	glEndList();
	BuildFont();
 
	glutTimerFunc(10timer1);
}
void BuildFont(void)
{
	HFONT font;
	HFONT oldfont;
 
	base = glGenLists(96);
	font = CreateFontA(-24,
		0,
		0,
		0,
		FW_BOLD,
		FALSE,
		FALSE,
		FALSE,
		ANSI_CHARSET,
		OUT_TT_PRECIS,
		CLIP_DEFAULT_PRECIS,
		ANTIALIASED_QUALITY,
		FF_DONTCARE | DEFAULT_PITCH,
		"Courier New");
 
	oldfont = (HFONT)SelectObject(hDCfont);
	wglUseFontBitmaps(hDC3296base);
	SelectObject(hDColdfont);
	DeleteObject(font);
}
void KillFont(GLvoid)
{
	glDeleteLists(base96);
}
 
//print function
void glPrint(const char *fmt, ...)
{
	char text[256];
	va_list ap;
	if (fmt == NULL)
		return;
 
	va_start(apfmt);
	vsprintf(textfmtap);
	va_end(ap);
 
	glPushAttrib(GL_LIST_BIT); {//push
		glListBase(base - 32);
		glCallLists(strlen(text), GL_UNSIGNED_BYTEtext);
	}glPopAttrib();//pop
}


cube를 구성할 사각형

/// <summary>
/// draw square
/// </summary>
/// <param name="a">a.</param>
/// <param name="b">The b.</param>
/// <param name="c">The c.</param>
/// <param name="d">The d.</param>
void quad(int aint bint cint d)
{
	glBegin(GL_QUADS);
	glColor3fv(colors[a]); glVertex3fv(vertices[a]);
	glColor3fv(colors[b]); glVertex3fv(vertices[b]);
	glColor3fv(colors[c]); glVertex3fv(vertices[c]);
	glColor3fv(colors[d]); glVertex3fv(vertices[d]);
}


메인함수

void main(int argccharargv[])
{
	glutInit(&argcargv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(500500);
	glutCreateWindow("xyz rotate");
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
 
	glutMouseFunc(mouseButton);
	glutMotionFunc(mouseMotion);
	glutTimerFunc(1000 / 30timer1); //timer 실행
	glutKeyboardFunc(keyboard);
	glutKeyboardUpFunc(keyupfunc);
 
	//bind menu with keyboard event
	glutCreateMenu(menu);
	glutAddMenuEntry("1"1);
	glutAddMenuEntry("2"2);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
 
	init();
	SetupRc();
	glutMainLoop();
}



실행영상



OpenGL - Perspective vs Orthographic (투시투영 vs 직교투영)

OrthoGraphic (직교투영), Perspective (투시투영) projection


둘의 차이를 간단히 설명하자면 직교투영은 무한한 거리에서 바라보는 것이라고 생각하면 된다.


가까운 거리에 있는 물체는 크게, 멀리 있는 물체는 작게 보이는 실생활과는 달리, 같은 크기의 물체는 모두 같게 보이는 것이다.


즉 그 반대인 투시투영은 실생활에서 우리 보는 원근감을 그대로 표현하는 projection이라고 생각하면 된다.


예제를 통해서 그 둘을 비교해 본다. 이번 예제는 같은 큐브를 두개의 관점에서 본다.


(앞의 예제와 마찬가지로, 생략된 코드는 아래의 링크를 참조한다)


2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기





소스코드


선언부

static int vi = 2;
static float viewer[3];
 
/// <summary>
/// The vertices {x, y, z}
/// </summary>
GLfloat vertices[8][3] = { { -1, -11 },{ -111 },
{ 111 },{ 1, -11 },{ -1, -1, -1 },
{ -11, -1 },{ 11, -1 },{ 1, -1, -1 } };
 
/// <summary>
/// The colors {R, G ,B]
/// </summary>
GLfloat colors[8][3] =
{ { 001 },{ 011 },
{ 111 },{ 101 },
{ 000 },{ 010 },
{ 110 },{ 100 } };
 
int W = 600H = 600;//width, height


키보드 이벤트

void menu(int item)
{
	keyboard((unsigned char)item00);
}
 
void keyboard(unsigned char keyint xint y)
{
	switch (key)
	{
	case 'q' | 'Q':
		exit(0); break;
	case VK_ESCAPE:
		exit(0); break;
	case 1://perspective
	{
		W += 1;
		vi = 1;
		glutReshapeWindow(WH);
	}	break;
	case 2://orthographic
	{
		vi = 2;
		W -= 1;
		glutReshapeWindow(WH);
	}break;
	}
}


초기화

void init(void)
{
	for (int i = 0i < 3i++) {
		viewer[i] = 2.5;
	}
}


사각형 draw

/// <summary>
/// draw square
/// </summary>
/// <param name="a">a.</param>
/// <param name="b">The b.</param>
/// <param name="c">The c.</param>
/// <param name="d">The d.</param>
void quad(int aint bint cint d)
{
	glBegin(GL_QUADS);
	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 RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	if (vi == 1)//perspective
	{
		vi = 1;
		gluLookAt(viewer[0], viewer[1], viewer[2], 000010);
		glutReshapeFunc(ChangeSize);
	}
	else//orthographic
	{
		vi = 2;
		glutReshapeFunc(ChangeSize);
		gluLookAt(viewer[0], viewer[1], viewer[2], 000010);
	}
	//draw cube
	quad(0321);
	quad(2376);
	quad(3047);
	quad(1265);
	quad(4567);
	quad(5401);
	glutSwapBuffers();
}


결과영상



OpenGL - 쉐이딩(Shading, line, flat smooth)

설명

삼각형으로 만든 원을 LineStrip, FlatShading, SmoothShading 효과를 줘 차이를 본다.


main에 없는 함수는 아래의 링크를 참조한다 (수정 x)

2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기


선언부

typedef GLfloat point3[3];
static float theta[3];
int num = 1;
void DrawTriangle(point3 &apoint3 &bpoint3 &c);
void Normalize(point3 &p);
void DivideTriangle(point3 &apoint3 &bpoint3 &cint n);
void CrossProduct(point3 &apoint3 &bpoint3 &cpoint3 &r);

Theta 초기화

void init(void) {
	for (int i = 0i < 3i++)
	{
		theta[i] = 0;
	}
}


렌더링 함수

void RenderScene(void) {
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(002000010);
 
	glEnable(GL_LIGHTING);//turn on light
	glEnable(GL_LIGHT0);//light0 turn on
 
	glRotatef(theta[2], 001);
	glRotatef(theta[1], 010);
	glRotatef(theta[0], 100);
 
	point3 v[4] = { { 001 },{ 00.942809, -0.333333 },{ -.816497, -0.471405, -0.333333 },{ 0.816497, -0.471405, -0.333333 } };
	int n = 3;
	DivideTriangle(v[0], v[1], v[2], n);
	DivideTriangle(v[0], v[2], v[3], n);
	DivideTriangle(v[0], v[3], v[1], n);
	DivideTriangle(v[3], v[2], v[1], n);
 
	glutSwapBuffers();
}

벡터 정규화

/// <summary>
/// Normalizes vector
/// </summary>
/// <param name="p">The p.</param>
void Normalize(point3 &p) {
	double d = p[0] * p[0] + p[1] * p[1] + p[2] * p[2];
	if (d > 0) {
		float len = (float)(1.0 / sqrt(d));
		p[0] *= lenp[1] *= lenp[2] *= len;
	}
}


벡터 외적

/// <summary>
/// Cross product vector a, b
/// </summary>
/// <param name="a">a.</param>
/// <param name="b">The b.</param>
/// <param name="c">The c.</param>
/// <param name="r">The r.</param>
void CrossProduct(point3 &apoint3 &bpoint3 &cpoint3 &r) {
	r[0] = (b[1] - a[1])*(c[2] - a[2]) - (b[2] - a[2])*(c[1] - a[1]);
	r[1] = (b[2] - a[2])*(c[0] - a[0]) - (b[0] - a[0])*(c[2] - a[2]);
	r[2] = (b[0] - a[0])*(c[1] - a[1]) - (b[1] - a[1])*(c[0] - a[0]);
	Normalize(r);//normalize
}


삼각형으로 나누기

/// <summary>
/// Divides the triangle recursively
/// </summary>
/// <param name="a">a.</param>
/// <param name="b">The b.</param>
/// <param name="c">The c.</param>
/// <param name="n">The n.</param>
void DivideTriangle(point3 &apoint3 &bpoint3 &cint n) {
	if (n > 0) {
		point3 v1v2v3;
		for (register int i = 0i < 3i++) {
			v1[i] = a[i] + b[i];
			v2[i] = b[i] + c[i];
			v3[i] = c[i] + a[i];
		}
		Normalize(v1); Normalize(v2); Normalize(v3);
		DivideTriangle(av1v3n - 1);
		DivideTriangle(bv2v1n - 1);
		DivideTriangle(cv3v2n - 1);
		DivideTriangle(v1v2v3n - 1);
	}
	else {
		DrawTriangle(abc);
	}
}

삼각형들 그리기

/// <summary>
/// Draws the triangle.
/// </summary>
/// <param name="a">point a.</param>
/// <param name="b">point b</param>
/// <param name="c">point c</param>
void DrawTriangle(point3 &apoint3 &bpoint3 &c) {
	if (num == 1// line strip
	{
		glDisable(GL_LIGHT0);//turn off light
		glBegin(GL_LINE_STRIP); {
			glNormal3fv(a); glVertex3fv(a);
			glNormal3fv(b); glVertex3fv(b);
			glNormal3fv(c); glVertex3fv(c);
		}glEnd();
	}
	else if (num == 2//flat shading
	{
		point3 n;
		CrossProduct(abcn);
		glBegin(GL_TRIANGLES);
		glNormal3fv(n);
		glVertex3fv(a);
		glVertex3fv(b);
		glVertex3fv(c);
		glEnd();
	}
	else //smooth shading
	{
		glBegin(GL_TRIANGLES); {
			glNormal3fv(a); glVertex3fv(a);
			glNormal3fv(b); glVertex3fv(b);
			glNormal3fv(c); glVertex3fv(c);
		}glEnd();
	}
}


각 shading마다 이벤트를 받는다.

void keyboard(unsigned char keyint xint y)
{
	switch (key)
	{
	case 1://line strip
	{
		num = 1;
	}break;
 
	case 2://flat shading
	{
		num = 2;
	}break;
	case 3://smooth shading
	{
		num = 3;
	}break;
	default:
		break;
	}
	RenderScene();
}
 
void shape(int item)
{
	keyboard((unsigned char)item00);
}

메인함수

void main(int argccharargv[]) {
	glutInit(&argcargv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(600600);
	glutCreateWindow("Shading");
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
 
	//show menu when right click
	glutCreateMenu(shape);
 
	//bind with key event
	glutAddMenuEntry("Wire frame"1);
	glutAddMenuEntry("Flat"2);
	glutAddMenuEntry("Smooth"3);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
 
	init();
	SetupRC();
	glutMainLoop();
}

결과물


OpenGL - 16개의 움직이는 랜덤 티팟

설명 : 16개의 teapot이 랜던한 색과 방향으로 회전한다.

이번에는 빛을 줘서 그림자 효과도 준다.


생략된 부분은 링크된 부분을 참고하세요(소스동일)

2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기


선언부

GLUquadricObj *p; void getaxis(int index); double getcolor(); int axi[16]; double colR[16]; double colG[16]; double colB[16]; static float theta[3]; GLdouble angle;


렌더링 함수

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(02.02.000001.00); //view point
 
	glEnable(GL_LIGHTING); //light on
	glEnable(GL_LIGHT0); //0th light
 
	GLfloat position0[4] = { 1001001001 };
	GLfloat ambient0[4] = { 000.6,0 };
	GLfloat diffuse0[4] = { 1.01.001 };
	GLfloat specular0[4] = { 1111 };
 
	glLightfv(GL_LIGHT0GL_POSITIONposition0);
	glLightfv(GL_LIGHT0GL_AMBIENTambient0);
	glLightfv(GL_LIGHT0GL_DIFFUSEdiffuse0);
	glLightfv(GL_LIGHT0GL_SPECULARspecular0);
 
	glColorMaterial(GL_FRONTGL_AMBIENT_AND_DIFFUSE);//light attributes is ambient, diffuse
	glEnable(GL_COLOR_MATERIAL);
 
	//set teapots attributes
	GLfloat mat_specular[4] = { 1,1,1,1 };
	GLfloat mat_shininess = 25.0f;
	glMaterialfv(GL_FRONTGL_SPECULARmat_specular);
	glMaterialf(GL_FRONTGL_SHININESSmat_shininess);
	double xp = -1.6;
	double yp = 2.4;
	int a = 0;
	int b = 0;
 
	for (int i = 0i < 4i++)
	{
		xp = -1.6// teapot move 1.6 with x-axis
		for (int k = 0k < 4k++)
		{
			glPushMatrix();//push
			glTranslatef(xpyp0.0);
 
			if (axi[a] == 0)
				glRotatef(angle100);
			else if (axi[a] == 1)
				glRotatef(angle010);
			else
				glRotatef(angle001);
			glColor3f(colR[b], colG[b], colB[b]);
			glutSolidTeapot(0.2);
			glPopMatrix();//pop
			a++;
			b++;
			xp = xp + 0.8;
		}
		yp = yp - 0.8;
	}
	glutSwapBuffers();
}


랜덤한 방향으로 회전하도록 x,y,z 방향을 제시해주는 함수

/// <summary>
/// set rotate direction random
/// </summary>
/// <param name="index">The index.</param>
void getaxis(int index)
{
	if (index == 0)
		glRotatef(angle100);
	else if (index == 1)
		glRotatef(angle010);
	else
		glRotatef(angle001);
}

주전자가 2도씩 회전함

/// <summary>
/// rotate teapot 2 degree
/// </summary>
/// <param name="value">The value.</param>
void rtimer(int value)
{
	angle += 2;
	glutTimerFunc(30rtimer0);
	glutPostRedisplay();
}


티팟에 줄 랜덤한 색을 제시

/// <summary>
/// Get random colors this instance.
/// </summary>
/// <returns></returns>
double getcolor(void)
{
	double c;
	c = (double)rand() / RAND_MAX;
	return c;
}


색과 방향 초기화

void init(void)
{
	srand(time(NULL));
	theta[0] = 0;
	theta[1] = 0;
	theta[2] = 0;
	for (int t = 0t < 16t++)
	{
		axi[t] = rand() % 3;
		colR[t] = (double)rand() / RAND_MAX;
		colG[t] = (double)rand() / RAND_MAX;
		colB[t] = (double)rand() / RAND_MAX;
	}
}


메인함수

void main(int argccharargv[])
{
	glutInit(&argcargv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(800800);
	glutCreateWindow("Ex4");
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
	glutTimerFunc(30rtimer1);
	init();
	SetupRc();
	glutMainLoop();
}


결과


OpenGL - 로봇 팔 만들기

설명

로봇의 팔을 만들어서 회전하고 꺽을수 있다.


이번에도 마찬가지로 소스에 대한 설명은 주석을 참조하세요

또한 생략된 소스는 맨 앞의 글을 참조하세요

2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기



로봇의 base

void base(void)
{
	glPushMatrix();//push
	{
		glColor3f(100);//red
		glTranslatef(0, -0.80);//y axis
		glRotatef(-90100);//x axis
		glRotatef(Base_Angle001);//z axis
		gluCylinder(p0.50.50.3201);//draw cylinder
	}
	glPopMatrix();//pop
}


로봇의 lower

/// <summary>
/// arm's lower
/// </summary>
void lower_arm(void)
{
	glPushMatrix();//push
	{
		glColor3f(010);//green
		glRotatef(Base_Angle010);//rotate with y axis
		glTranslatef(0, -0.70);//translate with axis
		glRotatef(Lower_Arm_Angle001);//rotate with z axis
		glTranslatef(00.50);//translate with y axis
		glScalef(0.210.2);//scaling
		glutWireCube(1);//draw cube
	}
	glPopMatrix();//pop
}


로봇의 upper

/// <summary>
/// arm's upper
/// </summary>
void upper_arm(void)
{
	glPushMatrix(); //push
	{
		glColor3f(001); // blue
		glRotatef(Base_Angle010); //rotate y axis
		glTranslatef(0, -0.70);//translate y axis
		glRotatef(Lower_Arm_Angle001);//rotate z axis
		glTranslatef(01.00);//translate y axis
		glRotatef(Upper_Arm_Angle001);//rotate z axis
		glTranslatef(00.40);//translate y axis
		glScalef(0.20.80.2);//scaling
		glutWireCube(1);//draw cube
	}
	glPopMatrix();//pop
}


렌더링 함수

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.50.50.5000010);//setting camera viewpoint
	base(); //draw base
	lower_arm(); //draw lower part
	upper_arm(); //draw upper part
	glutSwapBuffers();
}


스페셜 키 이벤트 (화살표4개, home, end)

/// <summary>
/// Special key event
/// </summary>
/// <param name="key">Special key.</param>
/// <param name="x">The x</param>
/// <param name="y">The y</param>
void specialkeys(int keyint xint y)
{
	switch (key)
	{
	case GLUT_KEY_UP//up arrow
		Lower_Arm_Angle += 2;
		break;
	case GLUT_KEY_DOWN//down arrow
		Lower_Arm_Angle -= 2;
		break;
	case GLUT_KEY_LEFT//left arrow
		Base_Angle -= 2;
		break;
	case GLUT_KEY_RIGHT//right arrow
		Base_Angle += 2;
		break;
	case GLUT_KEY_HOME//home key
		Upper_Arm_Angle += 2;
		break;
	case GLUT_KEY_END//end key
		Upper_Arm_Angle -= 2;
		break;
	default:
		break;
	}
}


메인함수

void main(int argccharargv[])
{
	glutInit(&argcargv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(500500);
	glutCreateWindow("Simple");
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
	glutSpecialFunc(specialkeys); //Special key event
	glutMouseFunc(mouseButton);
	glutMotionFunc(mouseMotion);
	glutTimerFunc(1000 / 30timer1);
	glutKeyboardFunc(keyboard);
	init();
	SetupRc();
	glutMainLoop();
}


타이머 함수

void timer(int value)
{
	if (rot)
	{
		theta += 2.0;
		if (theta >= 360.0)
			theta -= 360.0;
	}
	else
	{
		theta -= 2.0;
		if (theta <= 360.0)
			theta += 360.0;
	}
	glutTimerFunc(1000 / 30timer1);
	glutPostRedisplay();
}


결과


OpenGL - 정육면체 xyz축 회전


설명


정육면체를 'X'를 눌렀을때는 X축 회전, 'Y'를 눌렀을땐 Y축회전, 'Z'를 눌렀을때는 Z축 회전시킨다.



소스설명


앞의 소스와 중복되는 부분은 변경이 있기전까진 생략한다.

궁금하신분은 맨 앞의 게시물을 확인바랍니다.

2017/09/12 - [SW/OpenGL] - OpenGL - 사각형 회전, 색바꾸기



선언

static bool mouseLeftDown;//checking mouse click
static float point[2][2];
void mouseButton(int buttonint stateint xint y);
void mouseMotion(int xint y);
void keyboard(unsigned char keyint xint y);
void timer(int value);
void quad(int aint bint cint d);
static bool R = true;
static bool G = true;
static bool B = true;
static float theta;
bool rot = true;
int rx_axis = 0y_axis = 1z_axis = 0;


점8개와 색8개

/// <summary>
/// eight point to draw a cube
/// </summary>
GLfloat vertices[8][3] = { { -1, -11 },{ -111 },
{ 111 },{ 1, -11 },{ -1, -1, -1 },
{ -11, -1 },{ 11, -1 },{ 1, -1, -1 } };
 
 
 
/// <summary>
/// eight color each points
/// </summary>
GLfloat colors[8][3] =
{ { 001 },{ 011 },
{ 111 },{ 101 },
{ 000 },{ 010 },
{ 110 },{ 100 } };

colors는 r,g,b 값으로 색을 조합한다.



x,y,z 키에 대한 이벤트(x축, y축, z축)

void keyboard(unsigned char keyint xint y)
{
	switch (key)
	{
	case 'q' | 'Q':
		exit(0); break;
	case VK_ESCAPE:
		exit(0); break;
	case 1:
		exit(0); break;
	case 2:
		exit(0); break;
	case 'x' | 'X':
	{
		x_axis = 1;
		y_axis = 0;
		z_axis = 0;
		break;
	}
	case 'y' | 'Y':
	{
		x_axis = 0;
		y_axis = 1;
		z_axis = 0;
		break;
	}
	case 'z' | 'Z':
	{
		x_axis = 0;
		y_axis = 0;
		z_axis = 1;
		break;
	}
	default:
		break;
	}
}


렌더링함수

void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0.50.50.5000010); //view point
	glRotatef(thetax_axisy_axisz_axis);//rotate cube
 
	//draw a cube with 6 quadrature
	quad(0321);
	quad(2376);
	quad(3047);
	quad(1265);
	quad(4567);
	quad(5401);
	glEnd();
	glutSwapBuffers();
}


사각형을 그린다 위의 함수에서 6개의 사각형을 그리는데 사용하는 함수 quad

void quad(int aint bint cint d)
{
	glBegin(GL_QUADS);
	glColor3fv(colors[a]); glVertex3fv(vertices[a]);
	glColor3fv(colors[b]); glVertex3fv(vertices[b]);
	glColor3fv(colors[c]); glVertex3fv(vertices[c]);
	glColor3fv(colors[d]); glVertex3fv(vertices[d]);
}


마우스 클릭, 모션 함수 (마우스 왼쪽 클릭하면 회전방향이 바뀐다.)

void mouseButton(int buttonint stateint xint y)
{
	//mouse left button click
	if (button == GLUT_LEFT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
			if (!mouseLeftDown)
			{
				if (rot)
					rot = false;
				else
					rot = true;
			}
		}
		else if (state == GLUT_UP)
		{
			if (mouseLeftDown)
				mouseLeftDown = false;
		}
	}
	//mouse right button click
	else if (button == GLUT_RIGHT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
 
		}
		else if (state = GLUT_UP)
		{
 
		}
	}
	glutPostRedisplay();
}
 
void mouseMotion(int xint y)
{
	if (mouseLeftDown)
	{
		double viewport[4];
		glGetDoublev(GL_VIEWPORTviewport);
 
		point[1][0] = x / (float)viewport[2] * 500;
		point[1][1] = (viewport[3] - y) / (float)viewport[3] * 500;
	}
	glutPostRedisplay();
}


정육면체를 회전하기 위한 타이머

void timer(int value)
{
	if (rot)
	{
		theta += 2.0;
		if (theta >= 360.0)
			theta -= 360.0;
	}
	else
	{
		theta -= 2.0;
		if (theta <= 360.0)
			theta += 360.0;
	}
	glutTimerFunc(1000 / 30timer1);
	glutPostRedisplay();
}




초기화

void init(void)
{
	theta = 0.0f;
	glutTimerFunc(10timer1);
}
 
void SetupRc(void)
{
	glClearColor(1.0f1.0f1.0f1.0f);
	glEnable(GL_DEPTH_TEST);
}



결과



OpenGL - 3점을 찍어 삼각형 그리기


설명


마우스로 폼위의 3점을 찍으면 그 점을 꼭지점으로 삼각형을 그린다.




소스설명


설명은 주석으로 대체하였다.


parameter

#define POINTS 100
 
GLfloat pos[POINTS][2];//point array
GLfloat Width = 600.0//form width
GLfloat Height = 600.0//form height
GLint n = 0//number of points


렌더링함수

/// <summary>
/// Renders the scene.
/// </summary>
void RenderScene(void)
{
	int i;
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(100);//red color
	glPointSize(10.0f);//size 10
	glEnableClientState(GL_VERTEX_ARRAY);// enable array
 
	
	for (i = 0i < 3i++)
	{
		glBegin(GL_POINTS);//dot
		glVertex2f(pos[i][0], pos[i][1]);//dot position
	}
	if (i>2 && (pos[2][0] != 0))//draw triangle when the number of points are greater than two
	{
		glBegin(GL_TRIANGLES);
		glVertex2f(pos[0][0], pos[0][1]);
		glVertex2f(pos[1][0], pos[1][1]);
		glVertex2f(pos[2][0], pos[2][1]);
	}
	glEnd();
	glFlush();//flush
}


마우스 클릭 이벤트

/// <summary>
/// Mouse button event.
/// </summary>
/// <param name="button">The button.</param>
/// <param name="state">The state.</param>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
void mousebutton(int buttonint stateint xint y)
{
	if (button == GLUT_LEFT_BUTTON)
	{
		if (state == GLUT_DOWN)
		{
			pos[n][0] = x / Width;
			pos[n][1] = (Height - y) / Height;
			if (n > 2)//when then number of points greater than two
			{
				pos[n % 3][0] = pos[n][0];//x
				pos[n % 3][1] = pos[n][1];//y
			}
			n++;
			RenderScene();//rendering
		}
	}
}


윈폼 크기 변경 함수

/// <summary>
/// winform size changed
/// </summary>
/// <param name="w">width</param>
/// <param name="h">height</param>
void ChangeSize(int wint h)
{
	GLfloat asepectRatio;
 
	Width = w;
	Height = h;
 
	if (Height == 0)
		Height = 1;
	glViewport(00wh);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	
	gluOrtho2D(0.01.00.01.0);
}
void main(int argcchar *argv[])
{
	glutInit(&argcargv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
	glutInitWindowSize(WidthHeight);
	glutInitWindowPosition(00);
	glutCreateWindow("ex2");
	glClearColor(1.0f1.0f1.0f1.0f);
	glMatrixMode(GL_PROJECTION);
 
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
	glutMouseFunc(mousebutton);
 
	glutMainLoop();
}


결과물


OpenGL - 사각형 회전, 색바꾸기

OpenGL의 기초적인 함수를 사용해본다.


설명

r을 누르면 사각형의 회전방향이 바뀌고, 폼을 클릭하면 사각형의 색이 랜덤으로 바뀐다.


소스설명


키보드 입력등록

void menu(int item)
{
	keyboard((unsigned char)item00);
}


키보드 이벤트 등록

/// <summary>
/// key event registration
/// </summary>
/// <param name="key">The key.</param>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
void keyboard(unsigned char keyint xint y)
{
	switch (key)
	{
	case 'q' | 'Q':
		exit(0); break;
	case VK_ESCAPE:
		exit(0); break;
	case 1:
		exit(0); break;
	case 2:
		exit(0); break;
	case 'R' | 'r'//change rotate direction
		rotate(); break;
	default:
		break;
	}
}


렌더링함수

/// <summary>
/// Renders the scene.
/// </summary>
void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT);
 
	float cos_th = cos(theta * 3.14159 / 180.0);
	float sin_th = sin(theta * 3.14159 / 180.0);
 
	glColor3f(abc);
 
	//draw polygon
	glBegin(GL_POLYGON);
	{
		glVertex2f(cos_thsin_th);
		glVertex2f(-sin_thcos_th);
		glVertex2f(-cos_th, -sin_th);
		glVertex2f(sin_th, -cos_th);
	}
	glEnd();
	glutSwapBuffers();
}


초기화함수

void init(void)
{
	mouseLeftDown = false;
 
	point[0][0] = 0;
	point[0][1] = 0;
	point[1][0] = 0;
	point[1][1] = 0;
 
	theta = 0;
}
void SetupRc(void)
{
	glClearColor(1.0f1.0f1.0f1.0f);
}


윈폼의 크기가 변할때를 계산

/// <summary>
/// Changes the size.
/// when form size change
/// </summary>
/// <param name="w">width</param>
/// <param name="h">height</param>
void ChangeSize(int wint h)
{
	GLfloat aspectRatio;
 
	if (h == 0)
		h = 1;
 
	glViewport(00wh);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
 
	aspectRatio = (GLfloat)w / (GLfloat)h;
	if (w <= h)
	{
		gluOrtho2D(-2.02.0, -2.0*(float)h / (float)w2.0*(float)h / (float)w);
	}
	else
	{
		gluOrtho2D(-2.0*(float)w / (float)h2.0*(float)w / (float)h, -2.02.0);
	}
 
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}


사각형 회전을 위한 타이머

void timer(int value)
{
	if (rot)//rotate right
	{
		theta += 2.0;
		if (theta >= 360.0)
			theta -= 360.0;
	}
	else//rotate left
	{
		theta -= 2.0;
		if (theta <= 360.0)
			theta += 360.0;
	}
	glutTimerFunc(1000 / 30timer1);
	glutPostRedisplay();
}
 
void rotate()//exchange rotate direction
{
	if (rot)
		rot = false;
	else
		rot = true;
}


마우스 위치 함수

/// <summary>
/// Mouses the motion.
/// </summary>
/// <param name="x">The x.</param>
/// <param name="y">The y.</param>
void mouseMotion(int xint y)
{
	if (mouseLeftDown)
	{
		double viewport[4];
		glGetDoublev(GL_VIEWPORTviewport);
 
		point[1][0] = x / (float)viewport[2] * 500;
		point[1][1] = (viewport[3] - y) / (float)viewport[3] * 500;
	}
	glutPostRedisplay();
}


마우스 클릭 이벤트

/// <summary>
/// Mouse click event
/// </summary>
/// <param name="button">The button.</param>
/// <param name="state">button state.</param>
/// <param name="x">mouse's x</param>
/// <param name="y">mouse's y</param>
void mouseButton(int buttonint stateint xint y)
{
	int r;
	if (button == GLUT_LEFT_BUTTON//mouse left button
	{
		if (state == GLUT_DOWN)//clicked
		{
			if (!mouseLeftDown)
			{
			}
			r = rand() % 3;
			if (r == 0)
			{
				if (a == 0)
					a = 1;
				else
					a = 0;
				glutPostRedisplay();
			}
			else if (r == 1)
			{
				if (b == 0)
					b = 1;
				else
					b = 0;
				glutPostRedisplay();
			}
			else
			{
				if (c == 0)
					c = 1;
				else
					c = 0;
				glutPostRedisplay();
			}
		}
		else if (state == GLUT_UP)//unclicked
		{
			if (mouseLeftDown)
				mouseLeftDown = false;
		}
	}
}


가장 중요한 메인함수

/// <summary>
/// Mains the specified argc.
/// </summary>
/// <param name="argc">The argc.</param>
/// <param name="argv">The argv.</param>
void main(int argccharargv[])
{
	glutInit(&argcargv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(600600);//form's size
	glutCreateWindow("ex1");//form's name
	glutDisplayFunc(RenderScene);//display function registration
	glutReshapeFunc(ChangeSize);//reshape function registration
 
	glutMouseFunc(mouseButton);//mouse click function
	glutMotionFunc(mouseMotion);//mouse move function
	glutTimerFunc(1000 / 30timer1); //timer
	glutKeyboardFunc(keyboard);//keyboard functiom
 
	glutCreateMenu(menu);//when right mouse clicked
	glutAddMenuEntry("1"1);
	glutAddMenuEntry("2"2);
	glutAttachMenu(GLUT_RIGHT_BUTTON);
 
	init();
	SetupRc();
	srand(time(NULL));
	glutMainLoop();
}




'SW/OpenGL'에 해당되는 글 9건

1 →