#include <glut.h>
#include <gl.h>
#include <glu.h>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
using namespace std;
// Define for Enum value
enum Drawtype {points, line, triangle, polygons};
#define vertexcnt vertice.size()
// Structure for Vertex Information
struct vertex
{
GLint x,y,z;
};
// Vertex Matrix Information
vector<vertex> vertice;
// Menu Type
int type = points;
// Wire information
bool wire=false;
// 동적으로 찍을수 있게 하기위한 창의 사이즈 값.
GLint width,height;
GLfloat thick=1.0f;
// 컬러 설정을 위한 값.
GLfloat r=0.5,g=0.5,b=0.5;
//---------------------------------------------------------------------------------------------
// 화면 렌더링펑션
void MyDisplay( ){
int cnt=0;
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(r, g, b);
// 여기에서 드로잉
if(type == points)
{
glPointSize(thick);
for(cnt=0; cnt<vertexcnt; cnt++)
{
glBegin(GL_POINTS);
glVertex3f((GLfloat)vertice[cnt].x/width,(GLfloat)vertice[cnt].y/height,0.0);
glEnd();
}
}
else if(type == line)
{
glLineWidth(thick);
if(vertexcnt >1)
for(cnt=0; cnt<vertexcnt-1; cnt+=2)
{
glBegin(GL_LINES);
glVertex2f((GLfloat)vertice[cnt].x/width,(GLfloat)vertice[cnt].y/height);
glVertex2f((GLfloat)vertice[cnt+1].x/width,(GLfloat)vertice[cnt+1].y/height);
glEnd();
}
}
else if(type == triangle)
{
if(vertexcnt>2)
for(cnt=0; cnt<vertexcnt; cnt+=3)
{
if(!wire)
glBegin(GL_TRIANGLES);
else
glBegin(GL_LINE_LOOP);
if(cnt+2 < vertexcnt)
{
glVertex3f((GLfloat)vertice[cnt].x/width,(GLfloat)vertice[cnt].y/height,0.0);
glVertex3f((GLfloat)vertice[cnt+2].x/width,(GLfloat)vertice[cnt+2].y/height,0.0);
glVertex3f((GLfloat)vertice[cnt+1].x/width,(GLfloat)vertice[cnt+1].y/height,0.0);
}
glEnd();
}
}
else if(type == polygons)
{
if(wire)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
else
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_POLYGON);
for(cnt=0; cnt<vertexcnt; cnt++)
glVertex3f((GLfloat)vertice[cnt].x/width,(GLfloat)vertice[cnt].y/height,0.0);
glEnd();
}
glFlush( );
}
// 리사이징 이벤트
void MyReshape(int NewWidth, int NewHeight)
{
glViewport(0, 0, NewWidth, NewHeight);
width = NewWidth;
height = NewHeight;
printf("창사이즈 변경 : %d %d\n",NewWidth,NewHeight);
glMatrixMode(GL_PROJECTION); //투상행렬을 변환대상으로 설정
glLoadIdentity();
glOrtho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0);
}
// 키보드 일반키 이벤트
void keyboard(unsigned char pressed, int x, int y)
{
switch(pressed)
{
case 'w' :
if(wire)
wire = false;
else
wire = true;
break;
case ']':
thick += 0.15f;
break;
case '[' :
thick -= 0.15f;
break;
case 'q' :
case 'Q':
exit(0);
break;
case 'a':
r+=0.01;
break;
case 'z':
r-=0.01;
break;
case 's':
g+=0.01;
break;
case 'x':
g-=0.01;
break;
case 'd':
b+=0.01;
break;
case 'c':
b-=0.01;
break;
}
if(thick <= 0)
thick = 0;
if(thick >=5)
thick =5;
glutPostRedisplay();
}
// 마우스 클릭이벤트
void MyMouseClick(GLint Button, GLint State, GLint X, GLint Y){
int cnt=0;
if(Button==GLUT_LEFT_BUTTON && State==GLUT_DOWN){
vertex temp;
temp.x=X;
temp.y=Y;
temp.z=0;
vertice.push_back(temp);
//vertexcnt = vertice.size();
printf("[%d] ( %d, %d, %d)\n",vertexcnt,X,Y,0);
}
glutPostRedisplay();
}
void MyMainMenu(int entryID){
if(entryID == 1)
{
vertice.clear();
system("cls");
}
if(entryID == 2)
exit(0); //프로그램 종료
glutPostRedisplay();
}
void MySubMenu(int entryID){
if(entryID == points)
type = points; // 점그리기
else if (entryID == line)
type = line; // 선그리기
else if (entryID == triangle)
type = triangle; // 삼각형
else if (entryID == polygons)
type = polygons; // 폴리곤
glutPostRedisplay();
}
void setup()
{
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
}
int main(int argc, char** argv) {
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_RGB);
glutInitWindowSize(300, 300);
glutInitWindowPosition(0, 0);
glutCreateWindow("OpenGL Mj's Report");
glClearColor (1.0, 1.0, 1.0, 1.0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity( );
glOrtho(0.0, 1.0, 1.0, 0.0, -1.0, 1.0);
// 서브메뉴등록
GLint MySubMenuID = glutCreateMenu(MySubMenu);
glutAddMenuEntry("Points", 0);
glutAddMenuEntry("Lines", 1);
glutAddMenuEntry("Triangle", 2);
glutAddMenuEntry("Polygones", 3);
// 메뉴등록
GLint MyMainMenuID = glutCreateMenu(MyMainMenu);
glutAddSubMenu("Drawing", MySubMenuID);
glutAddMenuEntry("Clear", 1);
glutAddMenuEntry("Exit", 2);
// 버튼에대한 메뉴등록
glutAttachMenu(GLUT_RIGHT_BUTTON);
// 드로잉 펑션 등록
glutDisplayFunc(MyDisplay);
setup();
// 마우스 클릭이벤트 콜백함수 등록
glutMouseFunc(MyMouseClick);
// 키보드 이벤트 콜백함수 등록
glutKeyboardFunc(keyboard);
// 리사이징 이벤트 콜백함수 등록
glutReshapeFunc(MyReshape); //reshape callback
glutMainLoop( );
return 0;
}
// 추가된기능
// [, ] 키를 이용한 굵기조절
// az sx dc 를 이용한 r,g,b 색상조정
// w키를 이용한 와이어프레임 렌더링 조정 기능 추가
// 라인모드일시에 쭉 이어지는게 아니라 한 쌍씩 되게끔 수정.
// STL의 벡터를 이용한 다중 버텍스정보입력
// 창의 사이즈 조절에 따른 확장기능