E D R , A S I H C RSS

OpenGL스터디_실습 코드


skyLibrary_include


1. Intro


  • 이곳에 소스는 저의 github에도 올릴 예정이니 일일히 복붙하기 귀찮으신분들은 "https://github.com/skyLibrary/OpenGL_Practice"에서 받아가세요.

  • 코드를 실행해보시려면 OpenGL 설정하는것을 제대로 하시고 해야합니다. (링크 라이브러리 설정)

  • glut을 쓰고 있으니 이에 대한 설정을 하셔야 코드를 실행하실 수 있습니다.


2. chapter 2. OpenGL 맛보기




2.1. 사각형 애니메이션(RecAnime)


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

GLfloat x1 = 0.0f;
GLfloat y1 = 0.0f;
GLfloat rsize = 25;

GLfloat xstep = 1.0f;
GLfloat ystep = 1.0f;

GLfloat windowWidth;
GLfloat windowHeight;


//callback for rendering
void RenderScene(void)
{
	glClear(GL_COLOR_BUFFER_BIT);

	glColor3f(1.0f, 0.0f, 0.0f);

	glRectf(x1, y1, x1+rsize, y1-rsize);

	glutSwapBuffers();
}

//callback for timer
void TimerFunction(int value)
{
	//if rectangle collision to window x-axis wall, then reverse it's x-axis direction
	if(x1 > windowWidth - rsize || x1 < -windowWidth)
		xstep = -xstep;
	
	//if rectangle collision to window y-axis wall, then reverse it's y-axis direction
	if(y1 >windowHeight || y1 < -windowHeight + rsize )
		ystep = -ystep;

	x1 += xstep;
	y1 += ystep;

	if(x1 > windowWidth - rsize + xstep)
		x1 = windowWidth - rsize - 1;
	else if(x1 < -(windowWidth + xstep))
		x1 = -windowWidth - 1;
	
	if(y1 > (windowHeight + ystep))
		y1 = windowHeight - 1;
	else if(y1 < -(windowHeight - rsize +ystep))
		y1 = -windowHeight + rsize - 1;

	glutPostRedisplay();
	glutTimerFunc(33, TimerFunction, 1);
}

void SetupRC()
{
	glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
}

void ChangeSize(GLsizei w, GLsizei h)
{
	GLfloat aspectRatio;

	if(h==0)
		h = 1;

	glViewport(0,0,w,h);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	aspectRatio = (GLfloat)w/(GLfloat)h;
	if(w<=h)
	{
		windowWidth = 100;
		windowHeight  = 100/aspectRatio;
		glOrtho(-100.0, 100.0, -windowHeight, windowHeight, 1.0, -1.0);
	}
	else
	{
		windowWidth = 100*aspectRatio;
		windowHeight  = 100; 
		glOrtho(-windowWidth, windowWidth, -100.0, 100.0, 1.0, -1.0);
	}
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}


void main(void)
{
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
	glutInitWindowSize(800, 600);
	glutCreateWindow("simple -> GLRect -> Bounce");
	glutDisplayFunc(RenderScene);
	glutReshapeFunc(ChangeSize);
	glutTimerFunc(33, TimerFunction, 1);
	SetupRC();
	glutMainLoop();
}

3. chapter 3. 공간 내의 드로윙, 지오메트리와 버퍼




3.1. 나선모양으로 찍힌 점 크기 조절 및 안티알리어싱 적용


/* @skyLibrary
 * Title : spiral shape pointing
 * How to use :
 *		1. use up, down, left, right key in your key board. then its direction of viewpoint will be changed.  
 * Purpose :
 *		just practice OpenGL.
 *
 */

#include <gl/glut.h>
#include <gl/GL.h>
#include <gl/GLU.h>
#include <math.h>

//pie in math.
#define GL_PI 3.1415f

static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;


//callback for rendering
void RenderScene(void)
{
	GLfloat x,y,z,angle;
	GLfloat sizes[2];
	GLfloat step;
	GLfloat curSize;

	glClear(GL_COLOR_BUFFER_BIT);

	glPushMatrix();
	glRotatef(xRot, 1.0f, 0.0f, 0.0f);
	glRotatef(yRot, 0.0f, 1.0f, 0.0f);

	//get point size range and its interval. 
	glGetFloatv(GL_POINT_SIZE_RANGE, sizes);
	glGetFloatv(GL_POINT_SIZE_GRANULARITY, &step);

	curSize = sizes[0];

	z=-50.0f;
	for(angle = 0.0f; angle <= (2.0f*GL_PI)*3.0f; angle += 0.1f)
	{
		x = 50.0f*cos(angle);
		y = 50.0f*sin(angle);
		
		//set point size
		glPointSize(curSize);
		//set antializing
		glEnable(GL_POINT_SMOOTH);
		// Specify the point and move the Z value up a little	
		glBegin(GL_POINTS);
			glVertex3f(x, y, z);
		glEnd();

		z += 0.5f;
		curSize += step;
	}

	// Done drawing points
	

	// Restore transformations
	glPopMatrix();

	// Flush drawing commands
	glutSwapBuffers();
}

//angle change in case of finding key event command.
void SpecialKeys(int key, int x, int y)
{
	if(key == GLUT_KEY_UP)
		xRot-= 5.0f;

	if(key == GLUT_KEY_DOWN)
		xRot += 5.0f;

	if(key == GLUT_KEY_LEFT)
		yRot -= 5.0f;

	if(key == GLUT_KEY_RIGHT)
		yRot += 5.0f;

	if(key > 356.0f)
		xRot = 0.0f;

	if(key < -1.0f)
		xRot = 355.0f;

	if(key > 356.0f)
		yRot = 0.0f;

	if(key < -1.0f)
		yRot = 355.0f;

	// Refresh the Window
	glutPostRedisplay();
}

//register background color and base drawing color.
void SetupRC()
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

	glColor3f(0.0f, 1.0f, 0.0f);
}

//change window size event function
void ChangeSize(GLsizei w, GLsizei h)
{
	GLfloat nRange = 100.0f;

	if(h==0)
		h = 1;

	glViewport(0,0,w,h);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	
	if(w<=h)
	{
		
		glOrtho(-nRange, nRange, -nRange*h/w, nRange*h/w, nRange, -nRange);
	}
	else
	{
		
		glOrtho( -nRange*w/h, nRange*w/h, -nRange, nRange, nRange, -nRange);
	}
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

//entry point
void main(void)
{
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutCreateWindow("Points");
	glutDisplayFunc(RenderScene);
	glutSpecialFunc(SpecialKeys);
	glutReshapeFunc(ChangeSize);
	
	SetupRC();
	glutMainLoop();
}

3.2. 외곽선 내곽선을 구분짓는 상태적용 및 별 드로윙


/* 
 * @skyLibrary
 * Title : star drawing in 3D program
 * Date : 2013/7/7 ~ 2013/7/7
 * How to use : 
 *		1. use up, down, left, right key in your key board to move star in that way.
 *		2. click mouse right button and you can change the star shape statements by click each menu item.
 * Purpose :
 *		just practice OpenGL.
 */

#include <GL/glut.h>

#define SOLID_MODE 1
#define LINE_MODE 2
#define POINT_MODE 3

int iMode = SOLID_MODE;
GLboolean bEdgeFlag = true;

static GLfloat xRot = 0.0f;
static GLfloat yRot = 0.0f;

void RenderScene()
{
	glClear(GL_COLOR_BUFFER_BIT);

	if(iMode == LINE_MODE)
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);

	if(iMode == POINT_MODE)
		glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);

	if(iMode == SOLID_MODE)
		glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);

	glPushMatrix();
	glRotatef(xRot, 1.0f, 0.0f, 0.0f);
	glRotatef(yRot, 0.0f, 1.0f, 0.0f);

	//start drawing triangle
	glBegin(GL_TRIANGLES);
	
		//setup kind of line which is outter line or not.
		glEdgeFlag(bEdgeFlag);
		glVertex2f(-20.0f, 0.0f);
		glEdgeFlag(TRUE);
		glVertex2f(20.0f, 0.0f);
		glVertex2f(0.0f, 40.0f);

		glVertex2f(-20.0f,0.0f);
		glVertex2f(-60.0f,-20.0f);
		glEdgeFlag(bEdgeFlag);
		glVertex2f(-20.0f,-40.0f);
		glEdgeFlag(TRUE);

		glVertex2f(-20.0f,-40.0f);
		glVertex2f(0.0f, -80.0f);
		glEdgeFlag(bEdgeFlag);
		glVertex2f(20.0f, -40.0f);		
		glEdgeFlag(TRUE);

		glVertex2f(20.0f, -40.0f);		
		glVertex2f(60.0f, -20.0f);
		glEdgeFlag(bEdgeFlag);
		glVertex2f(20.0f, 0.0f);
		glEdgeFlag(TRUE);

		// Center square as two triangles
		glEdgeFlag(bEdgeFlag);
		glVertex2f(-20.0f, 0.0f);
		glVertex2f(-20.0f,-40.0f);
		glVertex2f(20.0f, 0.0f);
		
		glVertex2f(-20.0f,-40.0f);
		glVertex2f(20.0f, -40.0f);
		glVertex2f(20.0f, 0.0f);
		glEdgeFlag(TRUE);

	glEnd();

	glPopMatrix();

	glutSwapBuffers();
}

//menu event function
void ClickMenu(int value)
{
	switch(value)
	{
	case 1: iMode = SOLID_MODE; break;
	case 2: iMode = LINE_MODE; break;
	case 3: iMode = POINT_MODE; break;
	case 4: bEdgeFlag = true; break;
	case 5: 
	default: bEdgeFlag = false; break;
	}

	//repaint by calling callback function
	glutPostRedisplay();
}

//key event function
void SpecialKeys(int key, int x, int y)
{
	if(key == GLUT_KEY_DOWN)
	{
		xRot += 5.0f;
	}
	else if(key == GLUT_KEY_UP)
	{
		xRot -= 5.0f;
	}
	else if(key == GLUT_KEY_LEFT)
	{
		yRot += 5.0f;
	}
	else if(key == GLUT_KEY_RIGHT)
	{
		yRot -= 5.0f;
	}

	if(key > 365.0f)
		xRot = 0.0f;

	if(key < -1.0f)
		xRot = 355.0f;

	if(key > 356.0f)
		yRot = 0.0f;

	if(key < -1.0f)
		yRot = 355.0f;

	//repaint by calling callback function
	glutPostRedisplay();
}

//register backgroung color & base drawing color
void SetupRC()
{
	glClearColor( 0.0f, 0.0f, 0.0f, 1.0f);
	
	glColor3f(0.0f, 1.0f, 0.0f);
	
	//glShadeModel(GL_FLAT);

	//glFrontFace(GL_CCW);
}

void ChangeSize(int w, int h)
{
	GLfloat nRange = 100.0f;

	// Prevent a divide by zero
	if(h == 0)
		h = 1;

	// Set Viewport to window dimensions
    glViewport(0, 0, w, h);

	// Reset projection matrix stack
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	// Establish clipping volume (left, right, bottom, top, near, far)
    if (w <= h) 
		glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange, nRange);
    else 
		glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange, nRange);

	// Reset Model view matrix stack
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

void main()
{
	int nModeMenu;
	int nEdgeMenu;
	int nMainMenu;

	//register glut mode & create window
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutCreateWindow("star");
	
	//make Mode sub menu 
	nModeMenu = glutCreateMenu(ClickMenu);
	glutAddMenuEntry("Solid", 1);
	glutAddMenuEntry("Outline", 2);
	glutAddMenuEntry("Points", 3);

	//make Edge boolean sub menu
	nEdgeMenu = glutCreateMenu(ClickMenu);
	glutAddMenuEntry("On", 4);
	glutAddMenuEntry("Off", 5);

	//make main menu that add Mode menu and Edge Menu
	nMainMenu = glutCreateMenu(ClickMenu);
	glutAddSubMenu("Mode", nModeMenu);
	glutAddSubMenu("Edge", nEdgeMenu);
	glutAttachMenu(GLUT_RIGHT_BUTTON);

	//register callback function & event function
	glutReshapeFunc(ChangeSize);
	glutSpecialFunc(SpecialKeys);
	glutDisplayFunc(RenderScene);
	SetupRC();
	
	glutMainLoop();
}

3.3. 스텐실을 사용한 물결흠이 새겨진 사각형 애니메이션 그리기


/* 
 * @skyLibrary
 * Title : stencil pattern program
 * Date : 2013/7/7 ~ 2013/7/7
 * How to use : 
 *		just look.
 * Purpose :
 *		just practice OpenGL.
 */
#include <GL/glut.h>
#include <math.h>

//rectangle start origin and it's one side size.
GLfloat x = 0.0f;
GLfloat y = 0.0f;
GLfloat rsize = 25;

//rectangle movment way
GLfloat xStep = 1.0f;
GLfloat yStep = 1.0f;

//exectly half of width and height
GLfloat windowWidth;
GLfloat windowHeight;

//rectangle color RGB
GLfloat fR = 1.0f;
GLfloat fG = 0.0f;
GLfloat fB = 0.0f;

//redering function 
//-> draw stencil part and rectangle part
void RenderScene()
{
	GLdouble dRadian = 0.1;

	glClearStencil(0.0f);
	glEnable(GL_STENCIL_TEST);
	glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);

	glStencilFunc(GL_NEVER, 0.0f, 0.0f);
	glStencilOp(GL_INCR, GL_INCR, GL_INCR);
	
	glBegin(GL_LINE_STRIP);
		for(GLdouble angle = 0.0; angle < 400.0; angle += 0.1)
		{
			int t_x = sin(angle)*dRadian;
			int t_y = cos(angle)*dRadian;

			glVertex2f(t_x, t_y);
			dRadian *= 1.002;
		}
	glEnd();


	glStencilFunc(GL_NOTEQUAL, 1.0f, 1.0f);
	glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);

	glColor3f(fR,fG,fB);
	glRectf(x, y, x + rsize, y - rsize);
	
	glutSwapBuffers();
}

//inner event Timer function. 
//-> make inner event and manage dynamic data exception(bound exception + clipping exception). 
void Timer(int value)
{
	//if rectangle coordinate is out of window, then reverse it's movement.
	if(x > windowWidth - rsize || x < -windowWidth)
		xStep = -xStep;
	if(y < -windowHeight + rsize || y > windowHeight)
		yStep = -yStep;

	x += xStep;
	y += yStep;
	
	
	//clipping exception management.
	//it manage in case that window is resized by user so, clipping area x, y is smaller than window area x or y.
	if(x > windowWidth - rsize + xStep)
		x = windowWidth - rsize - 1;
	else if(x < -windowWidth - xStep)
		x = - windowWidth - 1;
	
	if(y > windowHeight + yStep)
		y = windowHeight - 1;
	else if(y < -windowHeight + rsize - yStep)
		y = -windowHeight + rsize - 1;
	

	//change rectangle RGB color 
	fR += 0.1f;
	if(fR > 5.0f)
	{
		fR = 0.0f;
		fG += 0.2f;
	}

	if(fG > 3.0f)
	{
		fG = 0.0f;
		fB = 0.3f;
	}

	if(fB > 2.5f)
	{
		fB = 0.0f;
	}

	glutPostRedisplay();
	glutTimerFunc(33, Timer, 1);
}

//register background color and base drawing color.
void SetupRC()
{
	glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
	
	glColor3f(1.0f, 0.0f, 0.0f);
}

//window resizing event function
//->resize viewport and clipping area 
void ChangeSize(int width, int height)
{
	GLfloat nRange = 100.0f;

	if(height == 0)
		height = 1;

	glViewport(0, 0, width, height);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	if(width <= height)
	{
		windowWidth = 100;
		windowHeight = nRange*height/width;
		glOrtho (-nRange, nRange, -windowHeight, windowHeight, -nRange, nRange);
	}
	else
	{
		windowHeight = 100;
		windowWidth = nRange*width/height;
		glOrtho (-windowWidth, windowWidth, -nRange, nRange, -nRange, nRange);
	}

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
}

//program entry
int main()
{
	//register GLUT_STENCIL(because of stencil buffer), if you want to use stensil function.
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_STENCIL);
	glutCreateWindow("Stencil");
	glutDisplayFunc(RenderScene);
	glutTimerFunc(33, Timer, 1);
	glutReshapeFunc(ChangeSize);

	SetupRC();
	glutMainLoop();
	return 1;
}

4. Chapter4. 지오메트리 변환과 파이프라인


4.1. 토러스(Torus)


4.2. 액터와 카메라를 통한 3D시점 변경

Valid XHTML 1.0! Valid CSS! powered by MoniWiki
last modified 2021-02-07 05:23:56
Processing time 0.0199 sec