2013-05-24 1 views
1

OpenGL 선택 모드가 더 이상 사용되지 않으며 HW 가속화되지 않았 음을 알고 있습니다. SGI 상자와 3DLabs GPU를 제외하고는 가속화되지 않았습니다. 내 코드가 아닌 것은 제거 할 수 없습니다. C++ 코드 :OpenGL Picking on Selection Mode

void GLWidget::Selection(int x,int y)           // This Is Where Selection Is Done 
{ 
GLint viewport[4]; 

glSelectBuffer(BUFSIZE,selectBuf); 
glRenderMode(GL_SELECT); 

glMatrixMode(GL_PROJECTION); 
glPushMatrix(); 
glLoadIdentity(); 

glGetIntegerv(GL_VIEWPORT,viewport); 
gluPickMatrix(x,viewport[3]-y,5,5,viewport); //defining the picking matrix 
gluPerspective(fov,ratio,0.1f,1000); 

glMatrixMode(GL_MODELVIEW); 

glInitNames(); 

glPushName(1);        //Pushing names on the stack 
glutSolidTorus(1, 2, 55, 55);    //Some draw in GL_SELECT mode 
glTranslatef(5.0f,1,5.0f); 
glPopName(); 
glPushName(2); 
glutSolidTorus(1, 2, 55, 55); 
glTranslatef(5.0f,1,5.0f); 
glPopName(); 
glPushName(3); 
glutSolidTorus(RADIUS1, RADIUS2, complex1, complex2); //public members 
glTranslatef(5.0f,1,5.0f); 
glPopName(); 

int hits; 

// restoring the original projection matrix 
glMatrixMode(GL_PROJECTION); 
glPopMatrix(); 
glMatrixMode(GL_MODELVIEW); 

// returning to normal rendering mode 
hits = glRenderMode(GL_RENDER); 

// if there are hits process them 
if (hits != 0){ 
    qDebug() << "Found " << hits << " hit(s)"; 
    processHits(hits,selectBuf); 
    } 
} 

이것은 * 이벤트 (GLWidget가 QGLWidget 파생 (QT 4.8))을 사용하여 호출 될 processHits 방법

void GLWidget::processHits (GLint hits, GLuint buffer[]) //Some prints 
{ 
unsigned int i, j; 
GLuint names, *ptr, minZ,*ptrNames, numberOfNames; 

ptr = (GLuint *) buffer; 
minZ = 0xffffffff; 
for (i = 0; i < hits; i++) { 
    names = *ptr; 
    ptr++; 
    if (*ptr < minZ) { 
     numberOfNames = names; 
     minZ = *ptr; 
     ptrNames = ptr+2; 
    } 
    ptr += names+2; 
} 

qDebug() << "Nearest: "; 
ptr = ptrNames; 
for (j = 0; j < numberOfNames; j++,ptr++) { 
    qDebug() << *ptr ; 
} 
} 

선택()이다. 그래서, 마우스 오른쪽 버튼을 클릭했을 때만 버퍼의 객체를 "끌어"스택의 이름을 누릅니다.

void GLWidget::mousePressEvent(QMouseEvent *event) 
{ 
lastPos = event->pos(); 
if (event->buttons() & GLUT_RIGHT_BUTTON){ 
    Selection(event->x(),event->y()); 
    } 
} 

paintGL() 메소드는이 코드로, 이때

void GLWidget::paintGL() 
{ 
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
glLoadIdentity(); 
glViewport (0, 0, w_screen, h_screen); 


    gluLookAt(objCamera->mPos.x, objCamera->mPos.y, objCamera->mPos.z, 
       0, objCamera->mView.y, 0, 
       objCamera->mUp.x, objCamera->mUp.y, objCamera->mUp.z);   

glutSolidTorus(1, 2, 55, 55); //draw some objects 
glTranslatef(5.0f,1,5.0f); 
glutSolidTorus(1, 2, 55, 55); 
glTranslatef(5.0f,1,5.0f); 
glutSolidTorus(RADIUS1, RADIUS2, complex1, complex2); 
glTranslatef(5.0f,1,5.0f); 
glTranslatef(-15.0f,-3,-15.0f); 
} 

동안

는 I 개체를 선택하고 그 ID를 검색하고, 수 동일한 XY 그들을 더 존재한다면 좌표 나는 가장 가까운 ID를 검색 할 수 있습니다. 이제 3 개의 다른 ID (1-2-3)로 3 개의 개체가 생겼습니다.

ID가 3 인 것은 고정 크기가 아닙니다. 내 질문은 : 버퍼를 사용하여 세 번째 토러스를 검색하고 크기를 변경하여 RADIUS1, RADIUS2, complex1, complex2를 수정하는 방법은 무엇입니까?

누군가가 작은 예를 쓸 수 있습니까?

히트가있을 때 스택에 히트의 이름 (glPushName으로 지정)을 사용합니다. 어떤 식 으로든 객체를 참조해야합니다 (이름이 포함 된 공용 멤버가 포함 된 문자열 일 수도 있습니다) , 그래서 그 속성을 변경할 수 있습니까?

답변

1

각 개체의 속성을 직접 저장해야합니다. 이름 스택에 이름을 올리면 나중에 각 부분에 데이터를 추가하여 나중에 어디에서 왔는지 효과적으로 식별 할 수 있습니다.

{float rad1, rad2, complex1, complex2;}와 같은 구조를 만들고 싶을 것입니다. }를 사용하여 각 원환 체에 대한 값을 저장합니다. 선택한 객체의 ID를 알았 으면 해당 구조체의 배열로 이동하여 해당 객체의 값을 수정합니다. 장면을 그릴 때마다이 구조체 배열을 실행하십시오.