OpenGL MFC Glut Tutorial Lesson1 + 상자 색 바꿔보기!

학교에서 컴퓨터 그래픽스 수업을 듣고 있습니다.

첫번째 과제는 GLUT를 이용한 선 그리기 + 삼각형 색 채우기 였는데요. 두번째 과제가 나올 듯 합니다.
Projection 관련 과제로 설명을 들었는데 교수님께서 연휴 때문인지 올리시질 않으시네요. 기한은 다가오는데….;;;

두 가지(Perspective/Orthogonal) Projection에 대해 구현해 가야 하므로 두 개를 내던가, 혹은 창 제어를 가능하게 해서 하나로 통합해서 내던가 둘 중 아무거나 선택해서 내면 될 거 같아서 교수님께서 언급하신 MFC로 제어하는 방법에 대해서 찾아보았는데요.
이 곳(http://www.kencocomputers.com/tutorials/)에 잘 설명되어 있네요^^

Lesson1을 따라해보다가 다이얼로그를 숨기지 않고 컨트롤들을 배치해서 값을 변경가능한가 테스트해보고 싶은 마음이 들어 박스의 색을 바꾸는 코드를 추가해서 한번 해 보았습니다.

일단 Lesson1을 따라해봅니다.
그리고 먼저 Play 버튼의 이벤트 핸들러 함수 내용 중 “this->ShowWindow(SW_HIDE)” 를 주석처리합니다.

void CGLUTLesson1Dlg::OnOK()
{
    glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);//set out options to RGB, double buffered and depth
    glutCreateWindow(“MFC Glut Lesson1”);//give the glut window a title
    // set glut callback functions
    glutDisplayFunc(display);//set our display callback
    glutReshapeFunc(resize);//set out resize callback
    //this->ShowWindow(SW_HIDE);// hide the mfc starter when the glut window opens
    glutMainLoop(); //start the glut main loop   

    CDialog::OnOK();
}

그리고 MFCOpenGL(원문에서는 MFCopenGL입니다.) 클래스에 float 형 변수 m_R, m_G, m_B를 추가해 줍니다.
이 값들을 다이얼로그에서 건드릴 것이므로 m_R, m_G, m_B 변수에 대한 Get/Set 함수를 추가하고, 세 개를 한꺼번에 바꾸는 SetColor 함수를 추가합니다. 그리고 m_R, m_G, m_B를 protected 속성으로 바꿉니다.

class MFCOpenGL 
{
public:
    …
    void SetColor(float r, float g, float b);

    void SetR(float r);
    void SetG(float g);
    void SetB(float b);

    float GetR();
    float GetG();
    float GetB();

protected:   
    float m_R;
    float m_G;
    float m_B;

};

뭐, 굳이 SetColor과 SetR/G/B, GetR/G/B 함수는 안써도 다 아시겠죠? ㅋㅋ

그리고 MFCOpenGL::display() 함수의 “glColor3f(1.0f, 0.0f, 0.0f);” 를 “glColor3f(m_R, m_G, m_B);”로 바꾸어 추가한 변수들로 그리도록 해줍니다.

void MFCOpenGL::display(void)
{
    glClearColor(0,0,0,0);//set the background color to black
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);
    glColor3f(m_R, m_G, m_B); //set cube color
    glutWireCube(30); //use the premade glut function to draw a wire cube of size 30
    glutSwapBuffers();
}

원래 값이 각각 1.0f, 0.0f, 0.0f 였으므로 생성자에서 이 값들을 m_R, m_G, m_B 에 넣어주면 좋겠네요.

MFCOpenGL::MFCOpenGL()
{
    m_R    = 1.0f;
    m_G    = 0.0f;
    m_B    = 0.0f;
}

그리고나서 원래 다이얼로그에 에디트 창 3개를 추가하고 각각에 연결된 float형 변수(m_R/m_G/m_B)를 추가합니다. 또 각 변수들로 SetColor을 호출하고 다시 그려줄 버튼도 하나 추가해 줍니다.

사용자 삽입 이미지

창이 뜰 때 만들어질 창의 색 값이 써지면 좋겠군요. OnInitDialog 함수에서 GetR/G/B함수를 이용해서 얻어오죠~

BOOL CGLUTLesson1Dlg::OnInitDialog()
{
    …

    // TODO: Add extra initialization here
    m_R = gl.GetR();
    m_G = gl.GetG();
    m_B = gl.GetB();

    UpdateData(FALSE);
   
    return TRUE;  // return TRUE  unless you set the focus to a control
}

그리고, SetColor버튼을 눌렀을 때 SetColor 함수를 호출하면 될 것 같군요. 값을 얻어와서 호출한 후에 display함수를 호출해서 그려줍시다.

void CGLUTLesson1Dlg::OnButtonSetColor()
{
    UpdateData(TRUE);
   
    gl.SetColor(m_R, m_G, m_B);
   
    display();
   
}

어디 그럼 이제 띄워볼까요?

사용자 삽입 이미지
잘~ 되네요. 흐흐~

컴퓨터 그래픽스 두번째 과제가 나오면 이 걸 좀 이용해서 이런식으로 해서 내야겠습니다. 흐흐..

CMonthCalCtrl의 버그

PRB: CMonthCalCtl::GetCurSel(CTime) Returns Wrong Value

Article ID : 235355
Last Review : November 21, 2006
Revision : 2.1
This article was previously published under Q235355

SYMPTOMS

When you use the CMonthCalCtrl::GetCurSel(CTime) to get the date selected
from the Month Calendar Common control, the date in the CTime class is incorrect.

Back to the top

CAUSE

MFC’s implementation of CMonthCalCtrl::GetCurSel() for the CTime class calls SendMessage(MCM_GETCURSEL, &sysTime) where sysTime is a SYSTEMTIME
structure. The MCM_GETCURSEL message does not fill in the hours,
minutes, and seconds part of the sysTime Structure with valid values.
However, the constructor for CTime class takes these values into consideration, so the date in CTime class is incorrect.

Back to the top

RESOLUTION


The workaround is to use the CMonthCalCtrl::GetCurSel(SYSTEMTIME*)
version of GetCurSel for this class to get the correct date. The code
will look like the following example:

   SYSTEMTIME sysTime;

m_MonthCal.GetCurSel(&sysTime);

sysTime.wHour = sysTime.wMinute = sysTime.wSecond = sysTime.wMilliseconds = 0;

CTime l_time(sysTime);


위와 같은 버그로 인해서 CMonthCalCtrl을 쓸 때는 위와 같은 형식으로 날짜/시간을 얻어와야 합니다.