![](/img/trans.png)
[英]How Do I draw Vertices using an Index Buffer using OpenGL ES 2.0 and Java (Android)
[英]How Do I UnProject Screen Coordinates in OpenGL ES 2.0 (Android)?
最近幾天,我一直在努力將應用程序的觸摸事件“取消投影”到渲染器的坐標空間中。 為了實現這一目標,我嘗試了各種自定義的非項目方法和替代技術(包括嘗試使用縮放因子和變換值來轉換坐標)無止境。 我已經得到接近(在我的觸摸稍微偏離),但是用我的努力GLU.gluUnProject
已經路要走 ,通常把坐標視圖四周的中心。 “最接近”的結果是通過Xandy的方法得出的,但是即使這些結果通常也不可行 。 我的主要問題是如何設置視口矩陣,是否要傳遞GLU.gluUnProject
正確的參數? 我的數學基於對這個問題的答案。 這是我的代碼的相關摘錄(顯示了如何設置矩陣和當前的嘗試):
public void onSurfaceChanged(GL10 gl, int width, int height) {
// Set the OpenGL viewport to fill the entire surface.
glViewport(0, 0, width, height);
...
float ratio = (float) width / height;
Matrix.frustumM(mProjectionMatrix, 0, -ratio, ratio, -1, 1, 3, 7);
}
public void onDrawFrame(GL10 gl) {
glClear(GL_COLOR_BUFFER_BIT);
Matrix.setLookAtM(mViewMatrix, 0, 0f, 0f, -4.5f, 0f, 0f, 0f, 0f, 1f, 0f);
Matrix.scaleM(mViewMatrix, 0, mScaleFactor, mScaleFactor, 1.0f);
Matrix.translateM(mViewMatrix, 0, -mOffset.x, mOffset.y, 0.0f);
Matrix.multiplyMM(mModelMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
...
}
public PointF convertScreenCoords(float x, float y) {
int[] viewPortMatrix = new int[]{0, 0, (int)mViewportWidth, (int)mViewportHeight};
float[] outputNear = new float[4];
float[] outputFar = new float[4];
y = mViewportHeight - y;
int successNear = GLU.gluUnProject(x, y, 0, mModelMatrix, 0, mProjectionMatrix, 0, viewPortMatrix, 0, outputNear, 0);
int successFar = GLU.gluUnProject(x, y, 1, mModelMatrix, 0, mProjectionMatrix, 0, viewPortMatrix, 0, outputFar, 0);
if (successNear == GL_FALSE || successFar == GL_FALSE) {
throw new RuntimeException("Cannot invert matrices!");
}
convert4DCoords(outputNear);
convert4DCoords(outputFar);
float distance = outputNear[2] / (outputFar[2] - outputNear[2]);
float normalizedX = (outputNear[0] + (outputFar[0] - outputNear[0]) * distance);
float normalizedY = (outputNear[1] + (outputFar[1] - outputNear[1]) * distance);
return new PointF(normalizedX, normalizedY);
}
convert4DCoords
只是一個輔助函數,它將數組的每個坐標(x,y,z)除以w。 mOffset
和mScaleFactor
是平移和縮放參數(由給定ScaleGestureDetector
我們的內GLSurfaceView
)
根據我已閱讀的所有內容,這應該可以正常工作,但是它始終是錯誤的,並且我不確定還有什么嘗試。 任何幫助/反饋將不勝感激!
我沒有仔細檢查您的所有數學知識,但您的某些矩陣運算和規范對我來說似乎是錯誤的。 這很可能是您問題的至少一部分。
首先看一下您所說的mViewMatrix
:
Matrix.setLookAtM(mViewMatrix, 0, 0f, 0f, -4.5f, 0f, 0f, 0f, 0f, 1f, 0f);
Matrix.scaleM(mViewMatrix, 0, mScaleFactor, mScaleFactor, 1.0f);
Matrix.translateM(mViewMatrix, 0, -mOffset.x, mOffset.y, 0.0f);
這不一定沒有錯。 但是大多數人可能只會調用第一部分,它是View矩陣setLookAtM()
的結果。 其余的看起來更像是模型矩陣。 但是由於渲染通常只使用View和Model矩陣的乘積,因此這只是術語。 可以說,存儲在mViewMatrix
是mViewMatrix
矩陣。
然后命名在這里變得陌生:
Matrix.multiplyMM(mModelMatrix, 0, mProjectionMatrix, 0, mViewMatrix, 0);
這將計算“投影”和“視圖”矩陣的乘積。 因此,這將是一個ViewProjection矩陣。 將其存儲在名為mModelMatrix
的變量中會造成混淆,我想您可能已經用這種命名方式設置了陷阱。
這將導致我們調用glUnproject()
:
GLU.gluUnProject(x, y, 0, mModelMatrix, 0, mProjectionMatrix, 0, viewPortMatrix, 0, outputNear, 0);
基於以上內容,您要傳遞的兩個矩陣參數(視口實際上不是矩陣)是ViewProjection和Projection矩陣。 根據方法定義,您應該傳遞ModelView和Projection矩陣。
由於我們確定了您所謂的mViewMatrix
對應於mViewMatrix
矩陣,因此,如果僅更改該參數,則應該可以更好地工作:
GLU.gluUnProject(x, y, 0, mViewMatrix, 0, mProjectionMatrix, 0, viewPortMatrix, 0, outputNear, 0);
然后,您可以擺脫根本不是模型矩陣的mModelMatrix
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.