2011-03-15 7 views
1

GLUT 함수를 사용하여 Open GL을 사용하여이 간단한 프로그램을 작성했습니다. 큐브를 조작하기 위해 glutKeyboardFunc() 함수를 사용하여 glutIdleFunc()가 호출되어 장면을 다시 그리는 지점에서 변수를 사용하여 카메라 또는 각도를 조작합니다. 내 rend 함수와 keycheck 함수 사이에서 얻을 수있는 유일한 방법은 내 변수와 두 함수가있는 전역 클래스를 만드는 것입니다.전역 클래스가 GLUT에 사용됩니까? 그렇다면 어떻게 피할 수 있습니까?

다음은 직접 내 질문과 관련된 코드입니다.

enter code here 

#include "stdafx.h" 
#include "OGL.h" 


void boingdraw(); 
void boingkeys(); 

OGL Tramp; //Global class 
void boingdraw() // called by glutDisplayFunc and kicks to my draw function 
{ 
    Tramp.rend(); 
} 
void boingkeys(unsigned char key, int x, int y) //called by glutKeyboardFunc 
                //kicks to my key switch 
{ 
    Tramp.Keycheck(key,x, y); 
} 




int main (int argc, char**argv) 
{ 





    glutInit(&argc, argv); 
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); 
    glutInitWindowSize(400,400); 
    glutCreateWindow("Testing"); 
    render3d(); 
    glutDisplayFunc(boingdraw); 
    glutKeyboardFunc(boingkeys); 
    glutIdleFunc(boingdraw); 
    glutReshapeFunc(resize); 
    glutMainLoop(); 
} 

OGL.h 파일에는 OGL 클래스의 2 가지 기능이 포함되어 있으며 초기화됩니다. 을 heres OGL.cpp 나는 내 수업에 들어가 그냥 메인에 초기화하려고 트램폴린과 함수 포인터의 많은 구현을 시도했지만 나는 그것이 오류없이 컴파일 할 수 없다

enter code here 
#include "stdafx.h" 
#include "OGL.h" 


OGL::OGL() 
{ 
    lx= 0.0; 
    updown= 0.0; 
    z= -5.0; 
    v1=0.0; 
    v2=1.0; 
    v3=0.0; 
} 
void OGL::rend() 
{ 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glMatrixMode(GL_MODELVIEW); 
    glLoadIdentity(); 
         // camera perspective variables used to move camera 
         //with keyfunc  
     gluLookAt(0.0,updown,z, 
       lx,0.0,0.0, 
       v1,v2,v3); 





    glPushMatrix(); 
    glTranslatef(-0.0,-0.0,0.0); 
       //angle if changed in keycheck func called by glutKeyboardFunc() 
    glRotatef(angle,0.0,1.0,0.0); 


    glBegin(GL_QUADS); 

       //draws stuff not important really 



    glEnd(); 
    glPopMatrix(); 
    glutSwapBuffers(); 

} 
void OGL::Keycheck(unsigned char key, int x, int y) 
     //Key switchboard with various checks for wsadqe and esc keys 

    { 
switch (key) 
    { 
    case 27: 
     { 
      exit(0);break; 
     } 
    case 97: 
     { 
       lx=lx+0.25; 

         break; 
     } 
    case 100: 
     { 
      { 
       lx=lx-0.25; 

         break; 
     } 
     } 
    case 101: 
     { 

      angle += 2.0f; 
      if(angle > 360) angle -= 360; 

      break; 

     } 
    case 113: 
     { 

      angle -= 2.0f; 
      if(angle < 0) angle += 362; 

      break; 
     } 
    case 115: 
     { 
      z=z-0.25; 

         break; 
     } 
    case 119: 
     { 
      z=z+0.25; 


     } 


    } 
} 

파일. glut을 사용할 때 전역 클래스가 나쁜 것으로 간주됩니까? 그렇다면 누군가이 문제를 해결하기 위해 내 코드와 함께 사용할 수있는 기술의 예를 들어 주시겠습니까?

"내 숙제를 마라."스레드 또는이 코드를 사용하는 예제 만 요구하면이 기술을 더 잘 이해할 수 있기 때문에이 코드를 사용하지 마십시오.

미리 감사 드리며 가난한 코드 (있는 경우)를 배우고 방금 배우고 나쁜 습관을 피우고 싶습니다.

+0

컴파일러 오류가 무엇입니까 : - 당신은 과잉 창을 만들 때 정적 콜백 함수의 각 내부

static std::map<int,MyGlutWindowClass*> windows; 

당신은 당신이지도에 추가하는 클래스 인스턴스를 조회? – user48956

+0

@ user48965 : 프로그래밍 스타일에 대한 질문입니다. @ 라이언 : 걱정 마세요, 당신은 GLUT로 가능한 한 이미 훌륭했습니다. 여러 개의 윈도우를 사용하고 있다면 @Chris Becke가 보여준 id-mapping을 사용하게 될 것입니다.나는 당신에게 몇 가지 충고를하고 싶습니다 : 각각과 모든 것을 클래스와 객체로 너무 열심히 포장하지 마십시오. 특히 초보자로서 OpenGL 상태의 클래스가 하위 수준이 될 것입니다. 언제 패턴을 깨는 지 아는 것이 중요하며 패턴 자체를 습득하는 것입니다! – datenwolf

답변

1

나는 GLUT에서 "전역이 항상 악"이라는 것을 조정하고 GLO에서 non-OO 콜백을 사용해야한다는 생각을하고 있다고 생각합니다.

간단한 답변 - 당신은 어떤 종류의 글로벌를 사용해야하는 것이 맞습니다.

좋은 프로그램 디자인을 위해서는 전역과 관련된 문제를 다시 생각해보십시오. "있는 그대로"의 코드는 전역이 단일 파일에 있다는 점에서 좋습니다. 파일 범위로 명시 적으로 표시하는 것이 더 좋을 것입니다.

static OGL Tramp; // Or use a local namespace. 

이것은 다소 캡슐화되었지만 콜백에서 액세스 할 수 있음을 의미합니다. 싱글 톤을 사용하면 거의 동일한 패턴을 따를 수 있습니다. OGL의 단일 인스턴스 만 원할 것이라는 확신이 든다면 괜찮습니다. 다른 인스턴스를 할 수 있습니다 경우에, 당신은 함수 호출 (아마도 정적 클래스 메소드)에 포장 할 수 있습니다

OGL& getOGLInstance(unsigned id = 0) 
{ 
    static OGL Tramp; // Or use a local namespace. 
    // Later, add in handling to find the instance given 'id'. 
    return Tramp; 
} 
1

기본 GLUT API는 과잉 Windows에서 사용자 데이터를 연관있는 방법이 없습니다.

그래서 일반적으로 정적 범위지도가 창 클래스 인스턴스 당 응용 프로그램에 매핑 glut 창 ID가 유지됩니다.

struct MyGlutWindowClass { 
    static void CallBack(){ 
    MyGlutWindowClass* self = windows[glutGetWindow()]; 
    self->OnCallback(); 
    } 
    void OnCallback(){ 
    AccessMemberVariables(); 
    } 

}; 
관련 문제