Java Android OpenGL ES:如何选择2D对象?
我一直在寻找OpenGL ES中的2D选择的入门教程。我经常看到关于3D的问题 我正在使用OpenGL ES在Android 4.0.3上设计一个基于二维平铺的关卡编辑器。在“标高编辑器”中,屏幕中央有一个二维黄色方形对象。我想做的就是检测这个物体是否被用户触摸过 在标高编辑器中,没有任何平铺重叠。相反,它们并排放置,就像MS Paint中位图图像中的两个相邻像素一样。我的目的是在level editor中分别检测每个方形对象的触摸事件 该对象是使用简单的顶点数组创建的,并使用GL_三角形绘制2个平面直角三角形。没有任何操作,也没有从文件或任何东西加载。我只知道,如果用户触摸任何一个黄色三角形,那么两个黄色三角形都将被选中 谁能给我一个提示,告诉我该怎么做?提前谢谢 编辑: 这是Java Android OpenGL ES:如何选择2D对象?,java,android,opengl-es,touch,Java,Android,Opengl Es,Touch,我一直在寻找OpenGL ES中的2D选择的入门教程。我经常看到关于3D的问题 我正在使用OpenGL ES在Android 4.0.3上设计一个基于二维平铺的关卡编辑器。在“标高编辑器”中,屏幕中央有一个二维黄色方形对象。我想做的就是检测这个物体是否被用户触摸过 在标高编辑器中,没有任何平铺重叠。相反,它们并排放置,就像MS Paint中位图图像中的两个相邻像素一样。我的目的是在level editor中分别检测每个方形对象的触摸事件 该对象是使用简单的顶点数组创建的,并使用GL_三角形绘制
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
对于二维投影,透视投影与正交投影相同吗?我看不出两者有什么不同
以下是创建曲面时的初始设置(一个扩展GLSurfaceView
并实现GLSurfaceView.Renderer
)的类:
你退房了吗
使用OpenGL ES使生活变得更加轻松。基本方法如下:
- 1和2。您必须跟踪渲染的位置 你的瓷砖。存储它们的位置和大小。矩形是一个矩形 结构方便。在您的示例中,它的计算如下 这当模型改变时,你必须重新计算它。我们称之为矩形r:
- 3-如果您正在使用 使用正交摄影机,您可以轻松地取消屏幕投影 坐标[x_屏幕,y_屏幕]如下(y类似):
- 4-对于每个矩形,检查[x_model;y_model]是否在其中
<强> [第二编辑] < /强>通过更新矩阵的方式,可以考虑使用带有SurvivSurviveWW的相机。WITH()/ 2,SurviveW.Head()/ 2。你们将屏幕上的1个像素和世界上的1个单位进行匹配,所以你们不需要取消投影任何东西。您可以替换我公式中的值,得到x_screen=x_model-(您需要翻转触摸事件的Y分量,因为Y在Java中向下增长,在GL中向上增长)
最后一句话。如果用户触摸点[x,y],检查[x,screenHeight-y]*是否点击了一些矩形,就完成了。 进行一些调试,记录接触点,看看它们是否符合预期。生成你们的矩形,看看它们是否和你们在屏幕上看到的相匹配,然后检查一个点是否在矩形内 我必须告诉你,你不应该将相机设置为屏幕尺寸,因为你的应用程序在不同的设备上看起来会截然不同。这是一个单独的话题,所以我不会再讲了,但是考虑一下用世界单位来定义你的模型——不依赖于屏幕大小。这太离题了,但我希望你已经很好地了解了你需要知道的东西 *我告诉过你的那一招。PS:坚持正字法投影(透视法使用起来会更复杂)。请允许我为您的问题发布第二个答案。这完全是高层次的/哲学的。也许这是一个愚蠢的、无用的答案,但我希望它能帮助一些计算机图形学新手将其思维转变为“图形模式” 你不能在屏幕上选择一个三角形。那个正方形不是两个三角形。那个正方形只是一堆黄色像素。OpenGL获取一些顶点,连接它们,处理它们,并在屏幕上为一些像素着色。在图形管道的某个阶段,甚至几何信息也会丢失,并且只有孤立的像素。这类似于打印机在纸上打印的信件。您通常不会处理纸张上的信息(好的,也许条形码阅读器会:D) 如果需要进一步处理图形,则必须对其建模,并使用辅助数据结构自行处理。这就是为什么我建议您创建一个矩形来为瓷砖建模。创建对象的虚拟“世界”,然后将其渲染到屏幕上。用户触摸事件不属于同一个世界,因此您必须将屏幕坐标“转换”为您的世界坐标。然后你改变了你的世界中的一些东西(可能是用户拖动她的手指,你必须移动一个对象),然后再次告诉OpenGL将你的世界渲染到屏幕上 您应该在模型上操作,而不是在视图上操作。网格更像是一种视图,所以你不应该把它们和
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);
}
r.x = yourTile.position.x -(deltaX - translateX)
r.y = yourTile.position.y -(deltaY - translateY)
r.width= yourTile.width //as there is no model scaling
r.height = yourTile.height//
x_model = ((x_screen/GL_viewport_width) -0.5 )*camera.WIDTH + Camera.position.x