簡體   English   中英

Android OpenGL ES:如何選擇2D對象?

[英]Android OpenGL ES: How do you select a 2D object?

我一直在尋找Stack Overflow中OpenGL ES中2D選擇的介紹。 我主要看到有關3D的問題。

我正在使用OpenGL ES在Android 4.0.3上設計基於2D磁貼的關卡編輯器。 在關卡編輯器中,有一個放置在屏幕中心的2D黃色方形對象。 我想要的只是檢測用戶是否觸摸過該對象。

在此輸入圖像描述

在關卡編輯器中,沒有任何切片重疊。 相反,它們並排放置,就像MS Paint中位圖圖像中的兩個鄰近像素一樣。 我的目的是在關卡編輯器中單獨檢測每個方形對象的觸摸事件。

使用簡單的頂點數組創建對象,並使用GL_TRIANGLES繪制2個直角三角形。 沒有操作,也沒有來自文件或任何東西的加載。 我唯一知道的是,如果用戶觸摸任何一個黃色三角形,那么將選擇兩個黃色三角形。

任何人都可以提供一個關於我需要這樣做的提示嗎? 提前致謝。

編輯:

這是draw()函數:

public void draw(GL10 gl) {
    gl.glPushMatrix();
    gl.glTranslatef(-(deltaX - translateX), (deltaY - translateY), 1f);
    gl.glColor4f(1f, 1f, 0f, 1f);
    //TODO: Move ClientState and MatrixStack outside of draw().
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertices);
    gl.glDrawArrays(GL10.GL_TRIANGLES, 0, 6);
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glPopMatrix();
}

編輯2:

我還在遺漏一些信息。 你在用相機嗎? 或者在模型渲染之前推送其他矩陣? 例如,如果您使用的是正交相機,則可以輕松地取消調整屏幕坐標[x_screen,y_screen](y類似):

我沒有使用相機,但我可能正在使用正交投影。 我不知道,因為我只是使用常見的OpenGL函數。 我推送和彈出矩陣,因為我計划將許多瓷磚(方形2D對象)與不同的平移矩陣進行整合。 沒有兩個瓦片具有相同的平移矩陣M.

在2D方面,透視投影是否與正投影相同? 我認為兩者之間沒有任何差異。

這是創建曲面時的初始設置(擴展GLSurfaceView ,並實現GLSurfaceView.Renderer ):

public void onSurfaceChanged(GL10 gl, int width, int height) {
    gl.glViewport(0, 0, width, height);
}

public void onSurfaceCreated(GL10 gl, EGLConfig arg1) {
    reset();
}
public void onDrawFrame(GL10 gl) {
    clearScreen(gl);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();
    gl.glOrthof(0f, super.getWidth(), 0f, super.getHeight(), 1, -1);
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();
    canvas.draw(gl);
}

private void clearScreen(GL10 gl) {
    gl.glClearColor(0.5f, 1f, 1f, 1f);
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
}

基本方法如下:

  1. 為每個“可觸摸”對象定義邊界框。 這可能只是一個矩形(x,y,寬度,高度)。
  2. 當您更新世界中的圖塊時,您將更新其邊界框(完全在世界坐標中)。
  3. 當用戶觸摸屏幕時,您必須將屏幕坐標取消投影到世界坐標
  4. 檢查未投影的點是否與任何邊界框重疊。

有關上一項的一些提示。 將帖子

  • 1和2.您應該跟蹤渲染瓷磚的位置。 存儲他們的位置和大小。 矩形是一種方便的結構。 在您的示例中,它可以像這樣計算。 並且在模型更改時您必須重新計算它。 讓我們稱之為Rectangle r:

     rx = yourTile.position.x -(deltaX - translateX) ry = yourTile.position.y -(deltaY - translateY) r.width= yourTile.width //as there is no model scaling r.height = yourTile.height// 
  • 3 - 如果您使用的是正交相機,您可以輕松地取消調整屏幕坐標[x_screen,y_screen],如下所示(y類似):

     x_model = ((x_screen/GL_viewport_width) -0.5 )*camera.WIDTH + Camera.position.x 
  • 4 - 對於每個矩形,檢查是否[x_model; y_model]在里面。

[第2次編輯]順便提一下你正在更新矩陣,你可以認為你正在使用帶有postView.width()/ 2,surfaceView.height()/ 2的相機。 您將屏幕上的1個像素與世界上的1個單位匹配,因此您無需取消任何項目。 您可以在我的公式上替換該值並獲取x_screen = x_model - (您需要翻轉觸摸事件的Y分量,因為Y在Java中向下增長,在GL中向上增長)。

最后的話。 如果用戶觸摸點[x,y],檢查[x,screenHeight-y] *是否擊中了一些矩形並完成了。 做一些調試,記錄觸摸點,看看它們是否符合預期。 生成矩形並查看它們是否與屏幕上顯示的一致,然后檢查點是否在矩形內。

我必須告訴您,您不應將相機設置為屏幕尺寸,因為您的應用在不同設備上看起來會有很大不同。 這是一個獨立的主題所以我不會再進一步​​,但考慮用世界單位來定義你的模型 - 獨立於屏幕尺寸。 這是如此偏離主題,但我希望你已經很好地了解了你需要知道的東西!

*我告訴你的翻轉。 PS:堅持使用正交投影(透視使用起來會更復雜)。

請允許我發一個問題的第二個答案。 這完全是更高層次/哲學的。 可能是一個愚蠢,無用的答案,但是,我希望它能幫助新的計算機圖形學家改變它的想法“圖形模式”。

您無法在屏幕上真正選擇三角形。 那個方塊不是2個三角形。 那個方塊只是一堆黃色像素。 OpenGL采用一些頂點,連接它們,處理它們並為屏幕上的一些像素着色。 在圖形管道的一個階段,甚至幾何信息都會丟失,而您只有孤立的像素。 這類似於打印機在紙上打印的字母。 您通常不處理紙張信息(好吧,也許是條形碼閱讀器:D)

如果需要進一步處理圖紙,則必須對其進行建模並使用輔助數據結構自行處理。 這就是為什么我建議你創建一個矩形來模擬你的瓷磚。 您可以創建想象中的“對象世界”,然后將它們渲染到屏幕上。 用戶觸摸事件不屬於同一個世界,因此您必須將屏幕坐標“轉換”為您的世界坐標。 然后你改變世界上的某些東西(可能是用戶拖動她的手指而你必須移動一個物體),然后又告訴OpenGL將你的世界渲染到屏幕上。

您應該對模型進行操作,而不是視圖。 網格更像是一個視圖,所以你不應該將它們與模型信息混合在一起,將兩者分開是一個很好的做法。 (拜托,專家糾正我,我是一個圖形愛好者)

你檢查過LibGDX了嗎?

使用OpenGL ES時,生活變得更加輕松。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM