[問題] OpenGL點選

看板C_and_CPP (C/C++)作者 (Nestarneal)時間13年前 (2013/03/15 21:30), 編輯推噓1(1032)
留言33則, 3人參與, 最新討論串1/1
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) VS 2010 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...) OpenGL、OpenMesh 問題(Question): 我先說明目前的狀況。 我利用 OpenMesh 將網格檔 (.obj) 讀進來後利用 OpenGL 畫在螢幕上。 整個網格檔由三角形構成,我希望能使用滑鼠點擊點、線或是面。 我利用反投影,將滑鼠座標轉換為空間座標,Code 如下: void GetOGLPos (int x, int y) { GLint viewport[4]; GLdouble modelview[16]; GLdouble projection[16]; GLfloat winX, winY, winZ; GLdouble posX, posY, posZ; glGetDoublev( GL_MODELVIEW_MATRIX, modelview ); glGetDoublev( GL_PROJECTION_MATRIX, projection ); glGetIntegerv( GL_VIEWPORT, viewport ); winX = (float)x; winY = (float)viewport[3] - (float)y; glReadPixels(x, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); gluUnProject(winX, winY, winZ, modelview, projection, viewport, &posX, &posY, &posZ); } 不過我目前遇到的問題是在於,我該如何以此為基礎,實現點擊的功能? 舉例來說,我有個三角形:● ● ● 假設這三角形的三個 Vertex 純粹由座標構成 (由 glVertex3f() 直接輸入座標) 那麼我至少還能一個一個搜尋找出我究竟是點到哪一個 Vertex 但如果我把三角形往左平移 12 個單位,則我點擊此三角形的頂點, 轉換後得到的座標為平移以後的座標,而非平移前的座標。 雖然很合理,可是這樣我就無法對我原本坐標值做搜尋, 也就是我沒辦法知道我究竟是點到哪個 Vertex。 想了很久都思考不到好的 idea, 可以的話,想請前輩們指點一下,謝謝。 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 111.251.154.94

03/15 23:36, , 1F
以你的例子來說,不要用反投影,直接用點投影到螢幕上的
03/15 23:36, 1F

03/15 23:37, , 2F
座標跟滑鼠座標比就好了
03/15 23:37, 2F

03/16 09:58, , 3F
那如果我例子中的三角形,上面那點座標是(0, 1, 0),
03/16 09:58, 3F

03/16 09:58, , 4F
往左平移 12 單位後座標變成(-12, 1, 0)
03/16 09:58, 4F

03/16 09:58, , 5F
但是我擁有的座標是原先的(0, 1, 0)而不是(-12, 1, 0)
03/16 09:58, 5F

03/16 09:59, , 6F
那就沒辦法比較了耶...
03/16 09:59, 6F

03/16 09:59, , 7F
因為我舉的是比較精簡的例子,實際上我可能對網格檔做
03/16 09:59, 7F

03/16 09:59, , 8F
了許多的平移、旋轉,甚至是從不同的方向去看,
03/16 09:59, 8F

03/16 09:59, , 9F
如此一來我擁有的座標是最原始的,
03/16 09:59, 9F

03/16 09:59, , 10F
好像就沒辦法比較了耶...
03/16 09:59, 10F

03/16 12:22, , 11F
你的 vertex 難道沒有 index 嗎? 你是怎樣逐一比較的?
03/16 12:22, 11F

03/16 12:47, , 12F
我是用 OpenMesh 提供的 iterator 再利用
03/16 12:47, 12F

03/16 12:47, , 13F
glVertex3dv() 來繪製。
03/16 12:47, 13F

03/16 12:47, , 14F
將滑鼠點擊的座標轉為空間座標以後,
03/16 12:47, 14F

03/16 12:48, , 15F
我可以用 iterator 來讓該座標與每個 Vertex 比較,
03/16 12:48, 15F

03/16 12:48, , 16F
差值小於我設定的門檻值,則判定我點到該點。
03/16 12:48, 16F

03/16 12:48, , 17F
但是如果經過平移旋轉等等的改變,
03/16 12:48, 17F

03/16 12:48, , 18F
比方說可能原先在(0, 0, 0)的點跑去(47, 48, 49)
03/16 12:48, 18F

03/16 12:48, , 19F
而我滑鼠點擊後轉換的空間座標為(47, 48, 49),
03/16 12:48, 19F

03/16 12:48, , 20F
但因為我原本有的點是(0, 0, 0)所以會找不到。
03/16 12:48, 20F

03/16 12:48, , 21F
也就是如果沒有平移旋轉等等的改變,
03/16 12:48, 21F

03/16 12:48, , 22F
我可以把滑鼠座標轉換後的空間座標與我的
03/16 12:48, 22F

03/16 12:48, , 23F
每一個 Vertex 進行比較,
03/16 12:48, 23F

03/16 12:49, , 24F
但如果經過了改變,就沒辦法找到了
03/16 12:49, 24F

03/16 12:49, , 25F
目前大概是這樣的狀況...
03/16 12:49, 25F

03/16 13:29, , 26F
iterator 裡面不就包含了原本 vertex 的資訊了嗎?
03/16 13:29, 26F

03/16 13:47, , 27F
是的。但如果有裡頭有個點為(0, 0, 0),經過變化
03/16 13:47, 27F

03/16 13:47, , 28F
位置跑到(47, 48, 49)。當滑鼠點擊(47, 48, 49)的位置
03/16 13:47, 28F

03/16 13:47, , 29F
時,理應是點擊到該點。
03/16 13:47, 29F

03/16 13:47, , 30F
但由於 iterator 的資訊是變化前,也就是(0, 0, 0),
03/16 13:47, 30F

03/16 13:47, , 31F
因此在搜尋時會認為沒有點到該點,
03/16 13:47, 31F

03/16 13:47, , 32F
但事實上是有點到的...
03/16 13:47, 32F

03/16 15:12, , 33F
先轉換到同一個 space 再比對,你的問題應該就解決了。
03/16 15:12, 33F
文章代碼(AID): #1HGo9-d2 (C_and_CPP)
文章代碼(AID): #1HGo9-d2 (C_and_CPP)